package MyGui;

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.text.DecimalFormat;
import java.io.*;
import java.text.NumberFormat;

import java.net.*;

import DataAccess.*;
import Engines.*;
import BackGround.*;
import Element.*;
import Element.Geom.*;
import DistSys.*;

public class MainMenuBar extends JMenuBar {
    MainFrame     mainFrame;  // MainApplet
    EngineThread  engineThread;
    private File  prjFile;

    EditActionQueue editActionQueueFg = new EditActionQueue();
    EditActionQueue editActionQueueBgLine = new EditActionQueue();
    EditActionQueue editActionQueueBgImage = new EditActionQueue();
    EditActionQueue activeQueue;

    //all top-level menus
    private JMenu     fileMenu, editMenu, viewMenu, shadingMenu, zoomMenu,
                      toolsMenu, analysisMenu, resultsMenu, helpMenu;
    //all menus:
    private JMenuItem newPrj, openPrj, openRemotePrj, importZones, savePrj,
                      savePrjAs, exportData, loadDftLib, loadBgImg, exit;
    private JMenuItem[] recentPrjs = new JMenuItem[PersonalInfo.MAX_RECENT_PRJ];

    private JMenuItem undo, redo, rotate, toggle, delete, copy, cmpInfo,
                      cmpInfoDebug, findCmp;
    private JMenu     select;
    private JMenuItem selectToSource, selectAwayFromSource, selectDeenergized,
                      selectStudyArea, selectZone, selectVoltageLevel,
                      selectOpenSwt, invertSelection, selectAll,
                      commonZone, commonDefaultTemplate, commonName,
                      commonPhase, commonVoltageLevel;
    private JMenuItem activeTemp, dftTemp;
    private JMenu     studyArea, group, lineAndCable;
    private JMenuItem setSelectionToStudyArea, addSelectionToStudyArea,
                      removeSelectionFromStudyArea, clearStudyArea;
    private JMenuItem ungroup;
    private JMenuItem combineSelectedSections, insertNode;

    /*private*/ JCheckBoxMenuItem
                      toolbar, legend, scale, gridLine, text, IECSymbols, ABB,
                      showNodes, snapToNodes;
    private JMenu     highLights;
    private JMenuItem highLightAll, highLightNone;
    private JCheckBoxMenuItem   highLightOpenPoints, highLightProtection,
                                highLightSect, highLightSelected;
    private JMenuItem layerMngr, satelliteView, refresh;
    /*private*/ JCheckBoxMenuItem freeze;

    private ButtonGroup shadingGroup;
    private JRadioButtonMenuItem   noShading, shadeByZone,
                      shadeByStudyArea, shadeByNomVoltage;
    private JMenuItem editLegend, grayScale;
    private Vector    custShade = new Vector(); // of JRadioButtonMenuItems

    private JMenuItem zoomOut, zoomIn, zoomAll, zoomPrev,
                      zoomWindow, zoomToScale, incExtents, decExtents,
                      centerDrawingToExtents;

    private JMenuItem txPara, dataMultiplier, dataModifier, relDataLib,
                      troubleShooting, exportToExcel, importFromExcel, scaleAndNorthArrow, options ;
    private JMenu     advancedTools;

    private JMenu     powerFlow, reliability, optimization, topology;
    private JMenuItem shtCkt, terminate;
    private JMenuItem quickFlow, netFlow, security, lossSum;
    private JMenuItem distRel, netRel, relInd, sensitivity, risk,
                      reliaOptions;
    private JMenuItem optSwt, optNormOpen;
    private JMenuItem buildConn, buildTree;

    private JMenuItem dataSummary, costSummary, querySearch, histogram,
                      traceToSrc;
    private JMenuItem onlineManual, submitFeedback, about;

    public static final int ABOUT_DLG         =0;   //AboutDlg
    public static final int ACTIVE_TEMP_DLG   =1;   //ActiveTempDlg
    public static final int COST_SUM_DLG      =2;   //CostSumDlg
    public static final int DATA_MODIFY_DLG   =3;   //DataModifyDlg
    public static final int DATA_SUM_DLG      =4;   //DataSumDlg
    public static final int EDIT_BGIMAGE_DLG  =5;   //EditBgLineDlg
    public static final int EDIT_BGLINE_DLG   =6;   //EditBgLineDlg
    public static final int EDIT_SHADING_DLG  =7;   //EditShadingDlg
    public static final int EDIT_TEMP_DLG     =8;   //EditTempDlg
    public static final int ELEM_INFO_DLG     =9;   //ElemInfoDlg
    public static final int EXPORT_DATA_DLG   =10;  //ExportDataDlg
    public static final int FIND_DLG          =11;  //FindDlg
    public static final int IMPORT_ZONES_DLG  =12;  //ImportZonesDlg
    public static final int LAYER_MNGR_DLG    =13;  //LayerMngrDlg
    public static final int LOSS_SUM_DLG      =14;  //LossSumDlg
    public static final int OPTIONS_DLG       =15;  //OptionsDlg
    public static final int QUERY_DLG         =16;  //QueryDlg
    public static final int RELIA_OPT_DLG     =17;  //ReliaOptionsDlg
    public static final int REL_IND_DLG       =18;  //RelIndDlg
    public static final int RISK_DLG          =19;  //RiskDlg
    public static final int SELECT_VOLT_DLG   =20;  //SelectVoltageLevelDlg
    public static final int SELECT_ZONE_DLG   =21;  //SelectZoneDlg
    public static final int SENSITIVITY_DLG   =22;  //SensitivityDlg
    public static final int TROUBLE_DLG       =23;  //TroubleShootingDlg
    public static final int TX_PARA_DLG       =24;  //TxParaDlg
    public static final int LOG_DLG           =25;  //LogDlg
    public static final int OPT_SWT_DLG       =26;  //Optimize switching devices
    public static final int RATED_PWR_DLG     =27;  //calc. rated power
    public int NUM_IPAD_DLGS = 28;
    Window[]  aIpadDlg = new Window[NUM_IPAD_DLGS];

    JFileChooser fileChooser = new JFileChooser();

    /*==============================================================
    ActionListeners for menu item under "Zoom" menu
    ==============================================================*/

    //alZoomPrev is shared with mainFrame.btnPanel
    ActionListener alZoomPrev = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            mainFrame.btnPanel.selectButton( mainFrame.btnPanel.BTN_ZOOM_PREV);

            //MapSF, prevViewPosition should be updated
            //after zoom_in, zoom out, zoom all, zoom to a specific scale
            Sys.prjInfo.toggleZoomFactor();
            Point pt=mainFrame.scrollPane.getViewport().getViewPosition();

            mainFrame.mainPanel.updateViewSize(pt);
            mainFrame.scrollPane.getViewport().setViewPosition( Sys.prevViewPosition );

            Rectangle newRect = mainFrame.scrollPane.getViewport().getViewRect();
            Sys.updateAllCoord( newRect );

            mainFrame.mainPanel.needRedraw = true;
            mainFrame.mainPanel.repaint();

            Sys.setPrevViewPosition( pt.x, pt.y); // record this in Sys.prevViewPosition
        }// end of actionPerformed : alZoomPrev
    };// end of new ActionListener():alZoomPrev

    ActionListener alZoomAll = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            zoomAll();
        }// end of actionPerformed : alZoomAll
    };// end of new ActionListener():alZoomAll

    void zoomAll(){
        //mainFrame.btnPanel.selectButton( mainFrame.btnPanel.BTN_ZOOM_ALL);
        int   x=mainFrame.scrollPane.getViewportBorderBounds().width;
        int   y=mainFrame.scrollPane.getViewportBorderBounds().height;
        Sys.calcMaxAndMin();  //updated store value
                              //should be redundant if dynamic topo. is done

        int tlx= (int) (Sys.prjInfo.dZoomFactor * Sys.SYS_MIN_X);
        int tly= (int) (Sys.prjInfo.dZoomFactor * Sys.SYS_MIN_Y);

        int width  = (int) (Sys.prjInfo.dZoomFactor * (Sys.SYS_MAX_X - Sys.SYS_MIN_X));
        int height = (int) (Sys.prjInfo.dZoomFactor * (Sys.SYS_MAX_Y - Sys.SYS_MIN_Y));
        Rectangle r= new Rectangle(tlx, tly, width, height);
        // r--> the rect similar to a dragged rect

        float a = ((float)x) / ((float)(Sys.SYS_MAX_X - Sys.SYS_MIN_X) ) ;
        float b = ((float)y) / ((float)(Sys.SYS_MAX_Y - Sys.SYS_MIN_Y) ) ;
        Sys.prjInfo.setZoomFactor(Math.min(a,b) );  // preScale also recorded

        x = mainFrame.scrollPane.getViewport().getViewPosition().x;
        y = mainFrame.scrollPane.getViewport().getViewPosition().y;
        Sys.setPrevViewPosition(x,y);  // record preViewPosition

        Point pt = mainFrame.mainPanel.locateViewPosition( r ); // pt--> new View Position

        mainFrame.mainPanel.updateViewSize( pt);
        mainFrame.scrollPane.getViewport().setViewPosition( pt);

        Rectangle newRect = mainFrame.scrollPane.getViewport().getViewRect();
        Sys.updateAllCoord( newRect );

        mainFrame.mainPanel.bZoomAll = true;
        mainFrame.mainPanel.needRedraw = true;
        mainFrame.mainPanel.repaint();
    }//end of zoomAll()

    ActionListener alZoomWindow = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            mainFrame.btnPanel.selectButton( mainFrame.btnPanel.BTN_ZOOM_WIN);
        }// end of actionPerformed():alZoomWindow
    };// end of ActionListener():alZoomWindow

    ActionListener alZoomOut = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            Sys.prjInfo.decZoomFactor();

            int x= mainFrame.scrollPane.getViewport().getViewPosition().x;
            int y= mainFrame.scrollPane.getViewport().getViewPosition().y;
            Sys.setPrevViewPosition(x,y);  // for zoom_prev

            int vpWidth  = mainFrame.scrollPane.getViewportBorderBounds().width;
            int vpHeight = mainFrame.scrollPane.getViewportBorderBounds().height;
            Rectangle r= new Rectangle(x, y, vpWidth, vpHeight);
            Point pt = mainFrame.mainPanel.locateViewPosition( r ); // pt--> new View Position

            mainFrame.mainPanel.updateViewSize( pt );  // from leftTop point & Sys.dZoom
            mainFrame.scrollPane.getViewport().setViewPosition( pt); // reset slider

            Rectangle newRect = mainFrame.scrollPane.getViewport().getViewRect();
            Sys.updateAllCoord( newRect );

            mainFrame.mainPanel.needRedraw = true;
            mainFrame.mainPanel.repaint();
        }//end of void actionPerformed():alZoomOut
    };//end of new ActionListener():alZoomOut

    ActionListener alZoomIn = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            Sys.prjInfo.incZoomFactor();

            int x= mainFrame.scrollPane.getViewport().getViewPosition().x;
            int y= mainFrame.scrollPane.getViewport().getViewPosition().y;
            Sys.setPrevViewPosition(x,y);  // for zoom_prev

            int vpWidth  = mainFrame.scrollPane.getViewportBorderBounds().width;
            int vpHeight = mainFrame.scrollPane.getViewportBorderBounds().height;
            Rectangle r= new Rectangle(x, y, vpWidth, vpHeight);
            Point pt = mainFrame.mainPanel.locateViewPosition( r ); // pt--> new View Position

            mainFrame.mainPanel.updateViewSize(pt);
            mainFrame.scrollPane.getViewport().setViewPosition( pt); // reset slider

            Rectangle newRect = mainFrame.scrollPane.getViewport().getViewRect();
            Sys.updateAllCoord( newRect );

            mainFrame.mainPanel.needRedraw = true;
            mainFrame.mainPanel.repaint();
       }//end of void actionPerformed():alZoomIn
    };//end of new ActionListener():alZoomIn

    ActionListener alZoomToScale = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            NumberFormat nf = NumberFormat.getNumberInstance();
            nf.setMaximumFractionDigits(6);
            nf.setGroupingUsed(false);

            double dCurrentScale = Sys.prjInfo.lengthPerUnit
                * SysConst.SCALEBAR_LENGTH / Sys.prjInfo.dZoomFactor;
            double dNewZoomFactor = 0.0;
            double dNewScale = 0.0;
            String msg =
                "Current scale = " + nf.format(dCurrentScale)
                + Sys.prjInfo.getUnitInString()+ ".\n"
                + "Please input new scale :";
            do {
                String inputValue = JOptionPane.showInputDialog(mainFrame, msg,
                    "Zoom to a Specific Scale", JOptionPane.QUESTION_MESSAGE);
                if (inputValue == null) {
                    // Cancelled by user
                    return;
                }
                try {
                    dNewScale = Float.parseFloat(inputValue);
                } catch(Exception e) {
                    dNewScale = 0.0;
                }
                if (dNewScale <= 0.0) {
                    JOptionPane.showMessageDialog(mainFrame, "'" + inputValue +
                        "' is not a valid scale factor.");
                }
            } while(dNewScale <= 0.0);

            dNewZoomFactor = Sys.prjInfo.lengthPerUnit
                * SysConst.SCALEBAR_LENGTH / dNewScale;
            Sys.prjInfo.setZoomFactor( dNewZoomFactor );

            int x= mainFrame.scrollPane.getViewport().getViewPosition().x;
            int y= mainFrame.scrollPane.getViewport().getViewPosition().y;
            Sys.setPrevViewPosition(x,y);  // for zoom_prev

            int vpWidth  = mainFrame.scrollPane.getViewportBorderBounds().width;
            int vpHeight = mainFrame.scrollPane.getViewportBorderBounds().height;
            Rectangle r= new Rectangle(x, y, vpWidth, vpHeight);
            Point pt = mainFrame.mainPanel.locateViewPosition( r ); // pt--> new View Position

            mainFrame.mainPanel.updateViewSize(pt);
            mainFrame.scrollPane.getViewport().setViewPosition( pt); // reset slider

            Rectangle newRect = mainFrame.scrollPane.getViewport().getViewRect();
            Sys.updateAllCoord( newRect );

            mainFrame.mainPanel.needRedraw = true;
            mainFrame.mainPanel.repaint();
        }//end of void actionPerformed():alZoomToScale
    };//end of new ActionListener():alZoomToScale

    /*==============================================================
    ActionListeners for menu item under "File" menu
    ==============================================================*/
    ActionListener alNewPrj = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            newProject();
        } // end of actionPerformed()
    }; // end of ActionListener()

    ActionListener alOpenPrj = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            // instantiate a FileChooser box
            fileChooser.setCurrentDirectory(Sys.personalInfo.getProjectsPath());
            fileChooser.setDialogTitle("Open a Project");
            fileChooser.resetChoosableFileFilters();
            fileChooser.addChoosableFileFilter(new MdbFileFilter());
            fileChooser.addChoosableFileFilter(new PadFileFilter());
            fileChooser.addChoosableFileFilter(new AllCompatiableFileFilter()); // show *.mdb, *.pad

            // get file name
            int returnVal = fileChooser.showOpenDialog(mainFrame);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                openProject(fileChooser.getSelectedFile());
            }
        } // end of actionPerformed():alOpenPrj
    }; // end of ActionListener():alOpenPrj

    ActionListener alOpenRecentPrj = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            Object src = evt.getSource();
            for (int i = 0; i < PersonalInfo.MAX_RECENT_PRJ; i++) {
                if (src.equals(recentPrjs[i])) {
                    openProject(Sys.personalInfo.getRecentProject(i));
                    return;
                }
            }
        } // end of actionPerformed():alOpenRecentPrj
    }; // end of ActionListener():alOpenRecentPrj

    boolean canSave(){
        if( SysConst.iAccessLevel < 0 ){
            String msg = "You can not save with your current access level.";
            JOptionPane.showMessageDialog(mainFrame, msg );
            return false;
        } else return true;
    }

    ActionListener alSavePrj = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if( !canSave() ){ return; }

            if (  prjFile == null || !prjFile.canWrite() ||
                  prjFile.getPath().toLowerCase().endsWith(".mdb") ) {
                // a new system, a read only project file, or a *.mdb prj file
                alSavePrjAs.actionPerformed( evt );
            } else {
                saveProject();
            }
        } // end of actionPerformed():alSavePrj
    }; // end of ActionListener():alSavePrj

    ActionListener alSavePrjAs = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if( !canSave() ){ return; }

            MdbFileFilter mdbFileFilter = new MdbFileFilter();
            PadFileFilter padFileFilter = new PadFileFilter();
            JpegFileFilter jpegFileFilter = new JpegFileFilter();
            // instantiate a FileChooser box
            fileChooser.setCurrentDirectory(Sys.personalInfo.getProjectsPath());
            fileChooser.setDialogTitle("Save Project As");
            fileChooser.resetChoosableFileFilters();
            fileChooser.setAcceptAllFileFilterUsed(false);
            
            //fileChooser.addChoosableFileFilter( mdbFileFilter );
            fileChooser.addChoosableFileFilter( padFileFilter );
            fileChooser.addChoosableFileFilter( jpegFileFilter );
            if (prjFile != null) { fileChooser.setSelectedFile(prjFile); }

            // get file name
            int returnVal = fileChooser.showSaveDialog(mainFrame);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                if( fileChooser.getFileFilter() == padFileFilter ){
                    if (!fileChooser.getSelectedFile().getPath().endsWith(".pad")) {
                        prjFile = new File(
                            fileChooser.getSelectedFile().getPath() + ".pad"); }
                    else {
                        prjFile = fileChooser.getSelectedFile(); }
                }
                /*added by Zoe start*/
                else if ( fileChooser.getFileFilter() == jpegFileFilter ){
                    if(!fileChooser.getSelectedFile().getPath().endsWith(".jpg")) {
                        prjFile = new File(
                            fileChooser.getSelectedFile().getPath() + ".jpg"); }
                    else {
                        prjFile = fileChooser.getSelectedFile(); }
                }
                /*added by Zoe end*/
                if (!prjFile.exists() ||
                    JOptionPane.showConfirmDialog(mainFrame,
                        "Overwrite existing file?", "Warning Message",
                        JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
                    // save file
                    saveProject();

                    mainFrame.setTitle(" " + prjFile.getName());
                    mainFrame.mainPanel.repaint();
                    Sys.personalInfo.addRecentProject(prjFile);
                    setRecentPrjMenuText();
                }
            }
        } // end of actionPerformed():alSavePrjAs
    }; // end of ActionListener()  :alSavePrjAs

    ActionListener alImportZones = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            if( aIpadDlg[IMPORT_ZONES_DLG]==null){
                aIpadDlg[IMPORT_ZONES_DLG] = new ImportZonesDlg( mainFrame,"Import Zones from Files");
            }
            aIpadDlg[IMPORT_ZONES_DLG].show();
       }//end of void actionPerformed():alImportZones
    };//end of new ActionListener():alImportZones

    ActionListener alExportData = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            if( aIpadDlg[EXPORT_DATA_DLG] == null){
                aIpadDlg[EXPORT_DATA_DLG] = new ExportDataDlg(mainFrame,
                    "Output Data and Results");
            }
            aIpadDlg[EXPORT_DATA_DLG].show();
        }//end of void actionPerformed():alExportData
    };//end of new ActionListener():alExportData

    ActionListener alLoadDftLib = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            Container thePane = mainFrame.getContentPane();
            try {
                // instantiate a FileChooser box
                fileChooser.setCurrentDirectory(Sys.personalInfo.getProjectsPath());
                fileChooser.setDialogTitle("Load Templates from another Project");
                fileChooser.resetChoosableFileFilters();
                //fileChooser.addChoosableFileFilter(new AllCompatiableFileFilter()); // show *.mdb, *.pad
                //fileChooser.addChoosableFileFilter(new MdbFileFilter());
                fileChooser.addChoosableFileFilter(new PadFileFilter());
                fileChooser.setAcceptAllFileFilterUsed(false);

                // get file name (*.mdb)
                int returnVal = fileChooser.showOpenDialog(mainFrame);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    Vector vUnsyncTmpltList = null;
                    File src = fileChooser.getSelectedFile();
                    thePane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                    // load dft template. This will update active template.
                    if( src.getPath().endsWith(".pad") ) {
                        BinaryFileAccessor bfa = new BinaryFileAccessor();
                        vUnsyncTmpltList = bfa.loadTemplateFromPadFile( src.getPath() );
                    }
//                    else if( src.getPath().endsWith(".mdb") ) {
//                        DBAccessor dba = new DBAccessor();
//                        vUnsyncTmpltList = dba.loadTemplateFromMdbFile(src.getPath());
//                    }
                    else  {
                        JOptionPane.showMessageDialog(mainFrame,
                            "Please select a (*.pad) file.");
                        thePane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                        return;
                    }
                    thePane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));

                    //to synchronize templates in vUnsync list
                    if( vUnsyncTmpltList.size()==0 ) {
                        JOptionPane.showMessageDialog(mainFrame,
                              "No new template found in file " + src.getPath());
                    } else {
                        if (JOptionPane.showConfirmDialog(mainFrame,
                                "Do you want to synchronize all loaded templated?",
                                "Please Confirm this:",
                                JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
                            thePane.setCursor(Cursor.getPredefinedCursor(
                                Cursor.WAIT_CURSOR));
                            Templates.syncTmpltInVector( vUnsyncTmpltList );
                        }
                    }//end of else : synchronize templates dialog box
                }//end of if users select a file name
            } catch (Exception e) {
                JOptionPane.showMessageDialog(mainFrame,
                    "Error Loading Global Templates\n"+e);
            } finally {
                thePane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            }
        } // end of actionPerformed(): alLoadDftLib
    }; // end of ActionListener() : alLoadDftLib

    ActionListener alLoadBgImg = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            Container thePane = mainFrame.getContentPane();
            try {
                // instantiate a FileChooser box
                fileChooser.setCurrentDirectory(Sys.personalInfo.getProjectsPath());
                fileChooser.setDialogTitle("Load Background Images");
                fileChooser.resetChoosableFileFilters();
                fileChooser.addChoosableFileFilter(new GifFileFilter());
                fileChooser.addChoosableFileFilter(new JpegFileFilter());
                fileChooser.addChoosableFileFilter(new PngFileFilter());
                fileChooser.addChoosableFileFilter(new AllImageFileFilter());

                // get file name (*.jpg, *.gif)
                int returnVal = fileChooser.showOpenDialog(mainFrame);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    File src = fileChooser.getSelectedFile();
                    if( !src.exists() ) {
                        JOptionPane.showMessageDialog(mainFrame, "File does not exist.");
                        return;
                    }
                    mainFrame.mainPanel.addBgImage( src.getPath() );
                }//end of if users select a file name
            } catch (Exception e) {
                JOptionPane.showMessageDialog(mainFrame,
                    "Error Loading Image.\n"+"Error = "+e);
            } finally {
                mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(
                    Cursor.DEFAULT_CURSOR));
            }
        } // end of actionPerformed(): alBgImg
    }; // end of ActionListener() : alBgImg

    ActionListener alExit = new ActionListener(){
        public void actionPerformed(ActionEvent evt) {
            int ret = JOptionPane.showConfirmDialog(mainFrame,
                "Save project before exit?", "Exit",
                JOptionPane.YES_NO_CANCEL_OPTION);
            if (ret == JOptionPane.YES_OPTION) {
                mainFrame.menuBar.alSavePrj.actionPerformed(evt);
            }
            if (ret == JOptionPane.YES_OPTION || ret == JOptionPane.NO_OPTION) {
                hideAllIpadDlgs(); //MyDlgFrame.hideAllDlgFrames();
                mainFrame.done();
                if (mainFrame.getApplet() != null) { // for applet
                    mainFrame.getApplet().startButton.setText(
                        "Click here to show iPAD");
                    mainFrame.hide();
                } else { // for application
                    System.exit(0);
                }
            }
        }//end of void actionPerformed():alExit
    };//end of new ActionListener():alExit

    /*==============================================================
    ActionListeners for menu item under "Edit" menu
    ==============================================================*/
    ActionListener alUndo = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(
                Cursor.WAIT_CURSOR));
            activeQueue.undo();
            redo.setEnabled( true);
            undo.setEnabled( activeQueue.canUndo() );
            //System.out.println( Sys.elemList.size() );
            mainFrame.mainPanel.needRedraw = true;
            mainFrame.mainPanel.repaint();
            mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(
                Cursor.DEFAULT_CURSOR));
       }//end of void actionPerformed()
    };//end of alUndo = new ActionListener();

    ActionListener alRedo = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(
                Cursor.WAIT_CURSOR));
            activeQueue.redo();
            undo.setEnabled( true );
            redo.setEnabled( activeQueue.canRedo() );
            mainFrame.mainPanel.needRedraw = true;
            mainFrame.mainPanel.repaint();
            mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(
                Cursor.DEFAULT_CURSOR));
       }//end of void actionPerformed()
    };//end of alRedo = new ActionListener();

    void pushIntoQueue(int id, Vector v ){
        mainFrame.menuBar.activeQueue.push( id, v);
        mainFrame.menuBar.setUndoEnabled(true);
        mainFrame.menuBar.setRedoEnabled(false);
    }//end of pushIntoQueue(int id, Vector v );

    void pushIntoQueue(int id, AbsElem elem){
        mainFrame.menuBar.activeQueue.push( id, elem);
        mainFrame.menuBar.setUndoEnabled(true);
        mainFrame.menuBar.setRedoEnabled(false);
    }//end of pushIntoQueue(int id, AbsElem elem);

    ActionListener alRotate = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            if( Sys.selectedList.size()==0 ) { return; }
            if( Sys.prjInfo.iActiveLayer < 0 ) { return; }
            mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(
                Cursor.WAIT_CURSOR));

            Vector v = ElemForUndoRedo.createEfurForVector(Sys.selectedList);
            for(int i=0;i<Sys.selectedList.size();i++){
                AbsElem theElem =(AbsElem)Sys.selectedList.elementAt(i);
                theElem.getElemGeomObj().incRotate();
                Sys.clearConn(theElem);
                Sys.updateConn(theElem);
            }
            mainFrame.menuBar.pushIntoQueue( EditAction.MOVE, v);

            mainFrame.mainPanel.needRedraw = true;
            mainFrame.mainPanel.repaint();
            mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(
                Cursor.DEFAULT_CURSOR));
       }//end of void actionPerformed()
    };//end of new ActionListener(); //alRotate

    ActionListener alToggle = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            if( Sys.selectedList.size()==0 ) { return; }
            if( Sys.prjInfo.iActiveLayer < 0 ) { return; }
            mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(
                Cursor.WAIT_CURSOR));
            Vector v = (Vector) Sys.selectedList.clone();
            Sys.toggleSelectedElem();
            mainFrame.menuBar.pushIntoQueue( EditAction.TOGGLE, v);
            mainFrame.mainPanel.needRedraw = true;
            mainFrame.mainPanel.repaint();
            mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(
                Cursor.DEFAULT_CURSOR));
        }//end of void actionPerformed():alToggle
    };//end of new ActionListener():alToggle

    ActionListener alDelete = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            if( Sys.selectedList.size()==0 ) { return; }
            mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(
                Cursor.WAIT_CURSOR));
            AbsElem elem;
            Vector vTmp = (Vector) Sys.selectedList.clone(); //DELETE
            if( Sys.selectedList.size()==1){
                elem = mainFrame.mainPanel.canSmartDelete((AbsElem)Sys.selectedList.get(0));
                if( elem != null ){
                    vTmp.add( new ElemForUndoRedo(elem) ); //MOVE
                    mainFrame.menuBar.pushIntoQueue(EditAction.SMART_DELETE, vTmp);
                } else {
                    mainFrame.menuBar.pushIntoQueue(EditAction.DELETE, vTmp);
                }
                mainFrame.mainPanel.doSmartDelete((AbsElem)Sys.selectedList.get(0) );
            } else {
                Sys.deleteSelectedElem();
                mainFrame.menuBar.pushIntoQueue(EditAction.DELETE, vTmp);
            }

            mainFrame.mainPanel.needRedraw = true;
            mainFrame.mainPanel.repaint();
            mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(
                Cursor.DEFAULT_CURSOR));
       }//end of void actionPerformed():alDelete
    };//end of new ActionListener():alDelete

    ActionListener alCopy = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            if( Sys.selectedList.size()==0 ) { return; }
            mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            Sys.copySelectedElem(); //all copied elem in selectedList now
            Sys.focusElem = null;
            Sys.displaceSelectedElem( 10, 10 );
            if( Sys.prjInfo.iActiveLayer > Sys.prjInfo.BG_LINE_LAYER ){
                Rectangle rect = mainFrame.scrollPane.getViewport().getViewRect();
                AbsElem elem;
                for(int i=0;i<Sys.selectedList.size();i++){
                    elem = (AbsElem) Sys.selectedList.elementAt(i);
                    if( elem.getElemGeomObj().isPartlyInARect(rect) ){
                        Sys.screenElemList.add(elem);
                    }
                    Sys.updateConn(elem);
                }
            }
            Vector v = (Vector) Sys.selectedList.clone();
            mainFrame.menuBar.pushIntoQueue( EditAction.ADD, v);
            mainFrame.mainPanel.needRedraw = true;
            mainFrame.mainPanel.repaint();
            mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
       }//end of void actionPerformed():alCopy
    };//end of new ActionListener():alCopy

    ActionListener alCmpInfo = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            showElemInfoForAnyCase();
        }//end of void actionPerformed() : alCmpInfo
    };//end of new ActionListener() : alCmpInfo

    ActionListener alCmpInfoDebug = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            if( Sys.selectedList.size()!=1){
                JOptionPane.showMessageDialog(mainFrame,
                    "Please select ONE component");
                return;
            }

            String str="";
            AbsElem e= (AbsElem)Sys.selectedList.firstElement();
            AbsElemGeom g=e.getElemGeomObj();

            int id=Sys.elemList.indexOf(e);
            id++; //user's version = developer's version +1;
            str +="My Self={ID="+id+"; Name="+g.getName()+"}\n";
            str +="=============================\n";

//            AbsElem parent = g.parent;
//            str += "Parent={";
//            if( parent!=null){ str += ( Sys.elemList.indexOf(parent) +1 ); }
//
//            AbsElem parent2;
//            if( g instanceof SwtGeom) { parent2 = ((SwtGeom)g).parent2; }
//            else if(e instanceof Switch3){ parent2=((ThreeNodeElemGeom)g).parent2;}
//            else parent2=null;
//            if( parent2!=null){ str += ", "+ (Sys.elemList.indexOf(parent2)+1); }
//            str +="}\n";
//
//            str +="Child ={";
//            for (int i=0;i<g.childList.size();i++){
//                AbsElem  e2= (AbsElem)g.childList.elementAt(i);
//                str += ( Sys.elemList.indexOf(e2) +1 );
//                if( i != (g.childList.size()-1) ) str +=",";
//            }
//            str +="}\n";
//            str +="============================\n";

            str +="Conn 1 ={";
            for (int i=0;i<g.conn1.size();i++){
                AbsElem e2 = (AbsElem)g.conn1.elementAt(i);
                str += ( Sys.elemList.indexOf(e2) +1 );
                if( i != (g.conn1.size()-1) ) str +=",";
            }
            str +="}\n";

            str +="Conn 2 ={";
            for (int i=0;i<g.conn2.size();i++){
                AbsElem e2 = (AbsElem)g.conn2.elementAt(i);
                str += ( Sys.elemList.indexOf(e2) +1 );
                if( i != (g.conn2.size()-1) ) str +=",";
            }
            str +="}\n";

            if( g instanceof ThreeNodeElemGeom){
            str +="Conn 3 ={";
            for (int i=0;i<((ThreeNodeElemGeom)g).conn3.size();i++){
                AbsElem e2 = (AbsElem)((ThreeNodeElemGeom)g).conn3.elementAt(i);
                str += (Sys.elemList.indexOf(e2) +1)+", ";
            }
            str +="}\n";
            }//end of if g is three-node-elem-geom

            str +="============================\n";
            str +="Node 1 =("+g.x1Stored+", "+g.y1Stored+") : ("+g.x1+", "+g.y1+")\n";
            str +="Node 2 =("+g.x2Stored+", "+g.y2Stored+") : ("+g.x2+", "+g.y2+")\n";
            if(g instanceof ThreeNodeElemGeom){
                ThreeNodeElemGeom g3 = (ThreeNodeElemGeom)g;
                str +="Node 3 =("+g3.x3Stored+", "+g3.y3Stored+") : ("+g3.x3+", "+g3.y3+")\n";
            }

//            str +="============================\n";
//            str +="Src Volt = "+ e.getData(AbsElem.DATA_SRC_VOLT)+"\n";
            JOptionPane.showMessageDialog(mainFrame, str);
       }//end of void actionPerformed()
    };//end of new ActionListener();

    ActionListener alFindCmp = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if( aIpadDlg[FIND_DLG] == null){
                aIpadDlg[FIND_DLG] = new FindDlg(mainFrame,"Find"); //non-module dlg.
            }
            aIpadDlg[FIND_DLG].show();
        }//end of actionPerformed()
    };// end of new ActionListener()

    /*==========================================
    All Menuitems under Select
        Trace to Source
        Trace away from Source
        Deenergized
        Study Area
        Select a Zone
        Open Switches
        Invert Selection
        All
    ===========================================*/
    ActionListener alSelectDeenergized = new ActionListener(){
        public void actionPerformed (ActionEvent evt){
            mainFrame.getContentPane().setCursor(
                Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            Sys.assignVoltageLevelToAllElements(false);
            Sys.clearSelectionAndFocus();
            Sys.focusElem = null;
            for (int i = 0; i < Sys.elemList.size(); i++) {
                AbsElem elem = (AbsElem) Sys.elemList.elementAt(i);
                if (elem.getResult(AbsElem.RES_NOMINAL_VOLT) == 0.0) {
                    AbsElemGeom geom = elem.getElemGeomObj();
                    if (geom instanceof GroupGeom ||
                        (geom instanceof SwtGeom &&
                         ((SwtGeom)geom).getIsEnergized())) {
                        // this is a energized element with no nominal voltage
                        // by algorithm design
                        continue;
                    }
                    Sys.addElemToSelection(elem);
                }
            }

            // // alTopology.actionPerformed(evt);
            // mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            // Sys.buildSystemTopo();
            // if( Sys.isRadial == false) {
            //     String msg="Please run Topology to make sure the system is radial!";
            //     JOptionPane.showMessageDialog(mainFrame, msg);
            //     mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            //     return;
            // }
            //
            // Sys.clearSelectionAndFocus();
            // Sys.findIsolated();

            mainFrame.getContentPane().setCursor(
                Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            mainFrame.mainPanel.setNeedRedraw(true);
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed();
    };//end of alSelectDeenergized;

    ActionListener alSelectTraceSource = new ActionListener(){
        public void actionPerformed (ActionEvent evt){
            if (Sys.focusElem == null) {
              if (Sys.selectedList.isEmpty()) {
                JOptionPane.showMessageDialog(mainFrame,
                                              "Please select one component!");
                return;
              } else
                Sys.focusElem = (AbsElem) Sys.selectedList.elementAt(0);
            }

            mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            if (evt.getSource() == selectToSource)
              Sys.TraceSource.selectTraceToSource(Sys.focusElem);
            else
              Sys.TraceSource.selectTraceAwayFromSource(Sys.focusElem);
            mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            mainFrame.mainPanel.needRedraw = true;
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed();
    };//end of alSelectTraceSource;

    ActionListener alSelectStudyArea = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            AbsElem elem;
            //AbsElemGeom geom;
            Sys.clearSelectionAndFocus();
            for(int i=0;i<Sys.elemList.size();i++){
                elem = (AbsElem)Sys.elemList.elementAt(i);
                //geom = (AbsElemGeom) elem.getElemGeomObj();
                if(elem.isInStudyArea() == true){
                    Sys.addElemToSelection(elem);
                }
            }
            mainFrame.mainPanel.needRedraw=true;
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed()
    };// end of new ActionListener()

    ActionListener alSelectOpenSwt = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            AbsElem elem;
            AbsElemGeom geom;
            Sys.clearSelectionAndFocus();
            for(int i=0;i<Sys.elemList.size();i++){
                elem = (AbsElem)Sys.elemList.elementAt(i);
                geom = (AbsElemGeom) elem.getElemGeomObj();
                if(geom instanceof SwtGeom && ((SwtGeom)geom).getIsOpen() ) {
                    Sys.addElemToSelection(elem);
                }
            }
            mainFrame.mainPanel.needRedraw=true;
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed()
    };// end of new ActionListener()

    ActionListener alInvertSelection = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            AbsElem elem;
            Vector v = new Vector(Sys.elemList);
            v.removeAll(Sys.selectedList);
            Sys.clearSelectionAndFocus();
            for(int i=0;i<v.size();i++){
                elem = (AbsElem) v.elementAt(i);
                Sys.addElemToSelection(elem);
            }
            v.removeAllElements();
            mainFrame.mainPanel.needRedraw=true;
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed()
    };// end of new ActionListener()

    ActionListener alSelectAll = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            AbsElem elem;
            Sys.clearSelectionAndFocus();
            for(int i=0;i<Sys.elemList.size();i++){
                elem = (AbsElem) Sys.elemList.elementAt(i);
                Sys.addElemToSelection(elem);
            }
            mainFrame.mainPanel.needRedraw=true;
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed()
    };// end of new ActionListener()

    ActionListener alSelectZone = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if (aIpadDlg[SELECT_ZONE_DLG] == null) {
                aIpadDlg[SELECT_ZONE_DLG] = new SelectZoneDlg(mainFrame,
                    "Select a Zone");
            }
            aIpadDlg[SELECT_ZONE_DLG].show();
        }//end of actionPerformed()
    };// end of new ActionListener()

     ActionListener alSelectVoltageLevel = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            Sys.assignVoltageLevelToAllElements(false);
            if (aIpadDlg[SELECT_VOLT_DLG] == null) {
                aIpadDlg[SELECT_VOLT_DLG] = new SelectVoltageLevelDlg(mainFrame,
                    "Select a Voltage Level");
            }
            aIpadDlg[SELECT_VOLT_DLG].show();
        }//end of actionPerformed()
    };// end of new ActionListener()

    ActionListener alCommon = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            Object  o = (JMenuItem) evt.getSource();
            AbsElem selectedElem, elem;
            AbsElemGeom selectedElemGeom, geom;

            if (Sys.selectedList.isEmpty()) {
                JOptionPane.showMessageDialog(mainFrame,"No Elements selected!");
                return;
            };
            if (o==commonVoltageLevel) {
                // calculate the voltage level of every element
                Sys.assignVoltageLevelToAllElements(true); // block warning msg
            };
            // reducing the number of the selected elements to a minimum for better performance
            // this loop is not necessary, but improves the performance if a lage number of elements is selected initially
            /* if the two compared elements have the same zone, name,etc.(depending on what should be common)
            // the first one is removed from the list , listsize and variable i decrease in this case */
            for(int i=0 ; i<Sys.selectedList.size() ; i++) {
                selectedElem=(AbsElem)Sys.selectedList.elementAt(i);
                selectedElemGeom=selectedElem.getElemGeomObj();
                if((i+1)<Sys.selectedList.size()) {
                    elem=(AbsElem)Sys.elemList.elementAt(i+1);
                    geom=elem.getElemGeomObj();
                }
                else { // end of list (important to leave the loop at the correct time)
                    break;
                };

                if(o==commonZone){
                    if (elem.getData(AbsElem.DATA_ZONE) ==
                            selectedElem.getData(AbsElem.DATA_ZONE)) {
                        Sys.removeElemFromSelection(selectedElem);
                        i--;
                    }
                }
                else if(o==commonDefaultTemplate){
                    AbsElem dftTemp = elem.getDftTemp();
                    if (dftTemp != null &&
                        dftTemp.equals(selectedElem.getDftTemp())) {
                        Sys.removeElemFromSelection(selectedElem);
                        i--;
                    };
                }
                else if(o==commonName){
                    String nameSelected = selectedElemGeom.getName();
                    String name = geom.getName();
                    if(name.equals(nameSelected)) {
                        Sys.removeElemFromSelection(selectedElem);
                        i--;
                    };
                }
                else if(o==commonPhase){
                    int phaseSelectedElem = selectedElem.getPhase();
                    int phaseElem = elem.getPhase();
                    if(phaseSelectedElem == phaseElem) {
                        Sys.removeElemFromSelection(selectedElem);
                        i--;
                    };
                }
                else if(o==commonVoltageLevel){
                    double dVolt1 = selectedElem.getResult(AbsElem.RES_NOMINAL_VOLT);
                    double dVolt2 = elem.getResult(AbsElem.RES_NOMINAL_VOLT);
                    double difference = Math.abs( dVolt1 - dVolt2 );
                    if(difference < Sys.DOUBLE_COMPARE * dVolt2) {
                        Sys.removeElemFromSelection(selectedElem);
                        i--;
                    };
                }
            } // end of for-loop (i<Sys.selectedList.size())
            // the the number of selected elements is now minimal for maximal performance

            int listSize=Sys.selectedList.size();
            for(int i=0 ; i<listSize ; i++) { // check all selected elements
                selectedElem=(AbsElem)Sys.selectedList.elementAt(i);
                selectedElemGeom=selectedElem.getElemGeomObj();

                // compare the selected elements with all the other elments in the system
                for (int j=0 ; j<Sys.elemList.size() ; j++) {
                    elem=(AbsElem)Sys.elemList.elementAt(j);
                    geom=elem.getElemGeomObj();

                    if(elem.equals(selectedElem)) continue; // elements should not be checked unnecessarily

                    if(o==commonZone){
                        if (elem.getData(AbsElem.DATA_ZONE) ==
                                selectedElem.getData(AbsElem.DATA_ZONE)) {
                            Sys.addElemToSelection(elem);
                        }
                    }
                    else if(o==commonDefaultTemplate){
                        AbsElem dftTemp = elem.getDftTemp();
                        if (dftTemp != null &&
                            dftTemp.equals(selectedElem.getDftTemp()))
                            Sys.addElemToSelection(elem);
                    }
                    else if(o==commonName){
                        String nameSelected = selectedElemGeom.getName();
                        String name = geom.getName();
                        if(name.equals(nameSelected))
                            Sys.addElemToSelection(elem);
                    }
                    else if(o==commonPhase){
                        int phaseSelectedElem = selectedElem.getPhase();
                        int phaseElem = elem.getPhase();
                        if(phaseSelectedElem == phaseElem)
                            Sys.addElemToSelection(elem);
                    }
                    else if(o==commonVoltageLevel){
                        double dVolt1 = selectedElem.getResult(AbsElem.RES_NOMINAL_VOLT);
                        double dVolt2 = elem.getResult(AbsElem.RES_NOMINAL_VOLT);
                        double difference = Math.abs( dVolt1 - dVolt2 );
                        if(difference < Sys.DOUBLE_COMPARE* dVolt2)
                            Sys.addElemToSelection(elem);
                    }
                }//end of for-loop(j<Sys.elemList.size())
            }//end of for-loop(i<listSize)
            mainFrame.mainPanel.needRedraw=true;
            mainFrame.mainPanel.repaint();
        }; // end of actionPerformd()
    }; //end of new ActionListener()

    ActionListener alActiveTemp = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if(aIpadDlg[ACTIVE_TEMP_DLG] ==null){
                aIpadDlg[ACTIVE_TEMP_DLG] = new ActiveTempDlg(
                    mainFrame,"Select Active Templates", true ); //module dialog
            }
            aIpadDlg[ACTIVE_TEMP_DLG].show();
        }//end of actionPerformed():alActiveTemp
    };// end of new ActionListener():alActiveTemp

     ActionListener alDftTemp = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if( aIpadDlg[EDIT_TEMP_DLG] == null ) {
                aIpadDlg[EDIT_TEMP_DLG] = new EditTempDlg(
                    mainFrame,"Edit Templates", true ); //module dialog
            } else {
                ((EditTempDlg)aIpadDlg[EDIT_TEMP_DLG]).updateAll();
            }
            aIpadDlg[EDIT_TEMP_DLG].show();
        }//end of actionPerformed():alDftTemp
    };// end of new ActionListener():alDftTemp


    //This is for the 4 menu items under Study Area: set, add, remove, clear;
    ActionListener alStudyArea = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            AbsElem elem;
            int sz;
            Object o = evt.getSource();
            //only "add" and "clear" need to redraw
            if(  o == setSelectionToStudyArea ){ //clear & add
                sz = Sys.elemList.size();
                for(int i=0;i<sz;i++){
                    elem = (AbsElem) Sys.elemList.elementAt(i);
                    elem.setData(AbsElem.DATA_STUDY_AREA, 0);
                }
                sz= Sys.selectedList.size();
                for(int i=0;i<sz;i++){
                    elem = (AbsElem) Sys.selectedList.elementAt(i);
                    elem.setData(AbsElem.DATA_STUDY_AREA, 1);
                }
                mainFrame.mainPanel.needRedraw=true;
            }
            else if( o == addSelectionToStudyArea){ //add only; no clear
                sz= Sys.selectedList.size();
                for(int i=0;i<sz;i++){
                    elem = (AbsElem) Sys.selectedList.elementAt(i);
                    elem.setData(AbsElem.DATA_STUDY_AREA, 1);
                }
            }
            else if( o == removeSelectionFromStudyArea){//remove
                sz= Sys.selectedList.size();
                for(int i=0;i<sz;i++){
                    elem = (AbsElem) Sys.selectedList.elementAt(i);
                    elem.setData(AbsElem.DATA_STUDY_AREA, 0);
                }
            }
            else if( o == clearStudyArea ){ //clear
                sz = Sys.elemList.size();
                for(int i=0;i<sz;i++){
                    elem = (AbsElem) Sys.elemList.elementAt(i);
                    elem.setData(AbsElem.DATA_STUDY_AREA, 0);
                }
                mainFrame.mainPanel.needRedraw=true;
            }
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed()
    };// end of new ActionListener():alStudyArea

    ActionListener alUngroup = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            int sz = Sys.selectedList.size();
            //boolean hasGroup=false;
            for(int i=0;i<sz;i++){
                AbsElem elem =(AbsElem) Sys.selectedList.elementAt(i);
                if( elem instanceof Group){
                    Sys.deleteElem(elem);
                    mainFrame.menuBar.pushIntoQueue(EditAction.DELETE, elem);
                    mainFrame.mainPanel.needRedraw=true;
                    mainFrame.mainPanel.repaint();
                    return; //delete only one group
                }
            }
        }//end of actionPerformed()
    };// end of new ActionListener():alUngroup

    ActionListener alCombineSelectedSections = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            AbsElem elem;
            AbsElemGeom geom;
            int firstType;
            boolean isSameType,isExisted;
            Point   node;
            Vector pointList = new Vector();
            int sz = Sys.selectedList.size();

            if(Sys.selectedList.size()<=1){
                JOptionPane.showMessageDialog(mainFrame,"Please select >=2 sections.");
                return;
            }

            isSameType= true;
            firstType = ((AbsElem)Sys.selectedList.elementAt(0)).getType();

            //type check: only merge sections of the same type
            if (firstType == SysConst.TYPE_LINE ||
                firstType == SysConst.TYPE_CABLE){
                for(int i=1;i<sz;i++){
                    elem = (AbsElem)Sys.selectedList.elementAt(i);
                    if (firstType != elem.getType()) { isSameType=false; }
                }
            }
            else { isSameType = false;}

            if( isSameType == false){
                JOptionPane.showMessageDialog(mainFrame,"Must be all lines or cables");
                return;
            }

            //find two nodes for the line/cable combined from selected sections
            for(int i=0;i<sz;i++){
                elem = (AbsElem)Sys.selectedList.elementAt(i);
                geom = elem.getElemGeomObj();

                node = new Point(geom.x1Stored, geom.y1Stored);  //check node 1
                isExisted=false;
                for(int k=0; k<pointList.size(); k++){
                    Point pt= (Point)pointList.elementAt(k);
                    if( pt.equals(node) ) { isExisted = true; break;}
                }
                if(isExisted) { pointList.remove(node); }
                else          { pointList.add(node);    }

                node = new Point(geom.x2Stored, geom.y2Stored);  // check node2
                isExisted=false;  //same code as above block
                for(int k=0; k<pointList.size(); k++){
                    Point pt= (Point)pointList.elementAt(k);
                    if( pt.equals(node) ) { isExisted = true; break;}
                }
                if(isExisted) { pointList.remove(node); }
                else          { pointList.add(node);    }
            }

            if( pointList.size()==0 || pointList.size()==1){
                JOptionPane.showMessageDialog(mainFrame,"Can't find two terminals. Circle existed.");
                return;
            }
            if( pointList.size() > 2){ //illegeal merge
                JOptionPane.showMessageDialog(mainFrame,"Can't merge these sections with >2 terminals");
                return;
            }

            //legal merge
            elem = (AbsElem) Sys.selectedList.elementAt(0);
            Line newLine = (Line) ((Line)elem).clone();
            LineGeom newLineGeom = (LineGeom) newLine.getElemGeomObj();

            double len=0.0;
            for(int i=0;i<sz;i++){
                elem =(AbsElem) Sys.selectedList.elementAt(i);
                geom = elem.getElemGeomObj();
                len += elem.getLength();
                //!!!!maybe need to sum other data fields !!!!!
            }
            newLine.setData(AbsElem.DATA_LENGTH, len);
            newLine.setCustomizedFlag( AbsElem.DATA_LENGTH, true);
            newLineGeom.setName( "Combined "
                + SysConst.ssType[SysConst.mapTypeToIndex(firstType)]);
            Point pt = (Point) pointList.elementAt(0);
            newLineGeom.setNode1FromStored(pt.x, pt.y ); //set node 1 of the new section
            pt = (Point) pointList.elementAt(1);
            newLineGeom.setNode2FromStored(pt.x, pt.y ); //set node 2 of the new section

            Vector v = (Vector) Sys.selectedList.clone();
            v.add( newLine);
            mainFrame.menuBar.pushIntoQueue( EditAction.COMBINE_LINES, v);

            Sys.deleteSelectedElem(); //connectivity cleared here
            Sys.addElem( newLine, true, true );

            mainFrame.mainPanel.needRedraw=true;
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed():alCombineSelectedSections
    };// end of new ActionListener():alCombineSelectedSections

    ActionListener alInsertNode = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
            Sys.isInsertNodeMode = true;
            //mainFrame.getContentPane().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        }//end of actionPerformed()
    };// end of new ActionListener()


    /*==============================================================
    ActionListeners for menu item under "View" menu
    ==============================================================*/
    ActionListener alLegend = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            Sys.prjInfo.showLegend = !(Sys.prjInfo.showLegend);
            mainFrame.mainPanel.needRedraw=true;
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed():alLegend
    };// end of new ActionListener():alLegend

    ActionListener alScale = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            Sys.prjInfo.showScale = !(Sys.prjInfo.showScale);
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed():alScale
    };// end of new ActionListener():alScale

    ActionListener alGridLine = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            Sys.prjInfo.showGridLine = !(Sys.prjInfo.showGridLine);
            //mainFrame.mainPanel.needRedraw = true;
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed():alGridLine
    };// end of new ActionListener():alGridLine

    ActionListener alText = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            Sys.prjInfo.drawText = !(Sys.prjInfo.drawText);
            //mainFrame.mainPanel.needRedraw=true;
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed():alText
    };// end of new ActionListener():alText

    ActionListener alShowNodes = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            Sys.prjInfo.showNodes = !(Sys.prjInfo.showNodes);
            //mainFrame.mainPanel.needRedraw=true;
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed():alShowNodes
    };// end of new ActionListener():alShowNodes

    ActionListener alHighLight = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            Object o =evt.getSource();
            MainMenuBar mb = mainFrame.menuBar;
            if( o == mb.highLightAll){
                highLightOpenPoints.setSelected(true);
                highLightProtection.setSelected(true);
                highLightSect.setSelected(true);
                highLightSelected.setSelected(true);
                Sys.prjInfo.isHighLightOpenPoints = true;
                Sys.prjInfo.isHighLightProtection = true;
                Sys.prjInfo.isHighLightSect = true;
                Sys.prjInfo.isHighLightSelected = true;
            }
            else if(o == mb.highLightNone){
                highLightOpenPoints.setSelected(false);
                highLightProtection.setSelected(false);
                highLightSect.setSelected(false);
                highLightSelected.setSelected(false);
                Sys.prjInfo.isHighLightOpenPoints = false;
                Sys.prjInfo.isHighLightProtection = false;
                Sys.prjInfo.isHighLightSect = false;
                Sys.prjInfo.isHighLightSelected = false;
            }
            else if( o == mb.highLightOpenPoints ){
                Sys.prjInfo.isHighLightOpenPoints = mb.highLightOpenPoints.isSelected();
            }
            else if( o == mb.highLightProtection ){
                Sys.prjInfo.isHighLightProtection = mb.highLightProtection.isSelected();
            }
            else if( o == mb.highLightSect ){
                Sys.prjInfo.isHighLightSect = mb.highLightSect.isSelected();
            }
            else if( o == mb.highLightSelected ){
                Sys.prjInfo.isHighLightSelected = mb.highLightSelected.isSelected();
            }

            //mainFrame.mainPanel.needRedraw=true;
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed():alHighLight
    };// end of new ActionListener():alHighLight

    ActionListener alLayerMngr = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if( aIpadDlg[LAYER_MNGR_DLG] == null){
                aIpadDlg[LAYER_MNGR_DLG] = new LayerMngrDlg(mainFrame, "Layer Manager");
            }
            aIpadDlg[LAYER_MNGR_DLG].show();
        }//end of actionPerformed():alLayerMngr
    };// end of new ActionListener():alLayerMngr

    ActionListener alFreeze = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            Sys.prjInfo.freeze = !(Sys.prjInfo.freeze);
            mainFrame.mainPanel.needRedraw=true;
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed():alFreeze
    };// end of new ActionListener():alFreeze

    ActionListener alRefresh = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            mainFrame.mainPanel.needRedraw=true;
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed():alRefresh
    };// end of new ActionListener():alRefresh

    /*==============================================================
    ActionListeners for menu item under "Shading" menu
    ==============================================================*/
    ActionListener alEditLegend = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            showEditShadingDlg();
       }//end of void actionPerformed()
    };//end of new ActionListener();

    ActionListener alShadeOpt = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            Object  o = (JRadioButtonMenuItem) evt.getSource();
            for (int i = 0; i < custShade.size(); i++) {
                if( o == custShade.elementAt(i)) {
                    setCurrentShadingOption(i);
                    break;
                }
            }

            if( o == noShading) {
                setCurrentShadingOption(ProjectInfo.SHADE_NONE);
            } else if( o == shadeByZone) {
                setCurrentShadingOption(ProjectInfo.SHADE_BY_ZONE);
            } else if( o == shadeByStudyArea) {
                setCurrentShadingOption(ProjectInfo.SHADE_BY_STUDY_AREA);
            } else if( o == shadeByNomVoltage) {
                setCurrentShadingOption(ProjectInfo.SHADE_BY_NOM_VOLTAGE);
            }
            mainFrame.mainPanel.setNeedRedraw(true);
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed()
    };// end of new ActionListener()

    /*==============================================================
    ActionListeners for menu item under "Tools" menu
    ==============================================================*/
    ActionListener alTxPara = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if( aIpadDlg[TX_PARA_DLG] == null){
                aIpadDlg[TX_PARA_DLG] = new TxParaDlg(
                    mainFrame, "Transformer Parameters");
            }
            aIpadDlg[TX_PARA_DLG].show();
        }//end of actionPerformed()
    };// end of new ActionListener()

    ActionListener alDataModifier = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if ( aIpadDlg[DATA_MODIFY_DLG] == null) {
                aIpadDlg[DATA_MODIFY_DLG] = new DataModifyDlg(mainFrame);
            }
            if (!aIpadDlg[DATA_MODIFY_DLG].isShowing()) {
                ((DataModifyDlg)aIpadDlg[DATA_MODIFY_DLG]).setArea(
                    Zone.ENTIRE_SYSTEM);
            }
            aIpadDlg[DATA_MODIFY_DLG].show();
        } // end of actionPerformed()
    }; // end of new ActionListener()

    ActionListener alTroubleShooting = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if( aIpadDlg[TROUBLE_DLG] == null){
                aIpadDlg[TROUBLE_DLG] = new TroubleShootingDlg(
                    mainFrame,"Trouble Shooting");
            }
            aIpadDlg[TROUBLE_DLG].show();
        }//end of actionPerformed()
    };// end of new ActionListener()

    ActionListener alExportToExcel = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            // instantiate a FileChooser box
            fileChooser.setCurrentDirectory(Sys.personalInfo.getProjectsPath());
            fileChooser.setDialogTitle("Export to a *.csv file");
            fileChooser.resetChoosableFileFilters();
            //fileChooser.addChoosableFileFilter(new CsvFileFilter());//zoe
            fileChooser.addChoosableFileFilter(new MatFileFilter());
            fileChooser.setAcceptAllFileFilterUsed(false);
            // get file name
            int returnVal = fileChooser.showOpenDialog(mainFrame);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                File f = fileChooser.getSelectedFile();
                /*if (!f.getPath().toLowerCase().endsWith(".csv")) {
                    f = new File( f.getPath() + ".csv");
                }*///zoe
                if (!f.getPath().toLowerCase().endsWith(".m")) {
                    f = new File( f.getPath() + ".m");
                }
                mainFrame.getContentPane().setCursor(
                    Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                try{
                    exportAllData( f );
                }catch(Exception e){
                    JOptionPane.showMessageDialog( mainFrame, e);
                }
                mainFrame.getContentPane().setCursor(
                    Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            }
        }//end of actionPerformed()
    };// end of new ActionListener()

    ActionListener alImportFromExcel = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            // instantiate a FileChooser box
            fileChooser.setCurrentDirectory(Sys.personalInfo.getProjectsPath());
            fileChooser.setDialogTitle("Import from a *.csv file");
            fileChooser.resetChoosableFileFilters();
            fileChooser.addChoosableFileFilter(new CsvFileFilter());
            fileChooser.setAcceptAllFileFilterUsed(false);
            // get file name
            int returnVal = fileChooser.showOpenDialog(mainFrame);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                mainFrame.getContentPane().setCursor(
                    Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                try {
                    importAllData(fileChooser.getSelectedFile());
                }catch(Exception e){
                  JOptionPane.showMessageDialog(mainFrame,
                      "Error occured. Error Msg = " + e);
                }
                mainFrame.getContentPane().setCursor(
                    Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            }
        }//end of actionPerformed()
    };// end of new ActionListener()

    ActionListener alOptions = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            showOptionsDlg(OptionsDlg.TAB_FIRST);
        }//end of actionPerformed()
    };// end of new ActionListener()

    /*==============================================================
    ActionListeners for menu item under "Analysis" menu
    ==============================================================*/
    ActionListener alBuildConn = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            mainFrame.getContentPane().setCursor(
                Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            UpdateProgressThread t=new UpdateProgressThread(
                mainFrame.btnPanel, ButtonPanel.CONN_MODE);
            t.start();
            Sys.findSysConn();
            mainFrame.getContentPane().setCursor(
                Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        }// end of actionPerformed
    };// end of new ActionListener()

    ActionListener alBuildTree = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            int iResult = JOptionPane.showConfirmDialog(mainFrame,
                "Force-run Connectivity?");
            if (iResult == JOptionPane.YES_OPTION ||
                iResult == JOptionPane.NO_OPTION) {
                mainFrame.getContentPane().setCursor(
                    Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                if (iResult == JOptionPane.YES_OPTION) {
                    UpdateProgressThread t=new UpdateProgressThread(
                        mainFrame.btnPanel, ButtonPanel.CONN_MODE);
                    t.start();
                    Sys.findSysConn();
                }

                iResult = Sys.buildSystemTopo(); // res =0 if radial tree built;
                mainFrame.getContentPane().setCursor(
                        Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));

                String sMessage;
                if (iResult == 0)
                    sMessage = "Radial tree structure successfully built!";
                else if (iResult == 1)
                    sMessage = "No Source found!";
                else
                    sMessage = "Loop or Transfer switches found. Error Code " +
                        iResult;
                JOptionPane.showMessageDialog(mainFrame, sMessage);
            }
        }// end of actionPerformed
    };// end of new ActionListener()

    boolean canAccessEngine(){
        if( SysConst.iAccessLevel <= 0  && Sys.elemList.size() > 500 ){
            String msg = "You can not run this analysis of a system with more\n"
              + "than 500 components at your current access level.";
            JOptionPane.showMessageDialog(mainFrame, msg);
            return false;
        } else return true;
    }

    ActionListener alQuickFlow = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            if( ! canAccessEngine() ){ return; }

            SysConst.progress = 0;
            UpdateProgressThread t = new UpdateProgressThread(
                mainFrame.btnPanel, ButtonPanel.ENGN_MODE);
            t.start();

            String strUrl = WebConst.getQuickflowURL() +
                "?WebPath=" + WebConst.getEngineWebPath() +
                "&PadPath=" + Sys.personalInfo.getTempPath().getPath() +
                "&Mode=1";
            engineThread = new EngineThread(mainFrame, strUrl,
                EngineThread.ENG_QUICKFLOW);
            engineThread.start();
        }// end of actionPerformed() :alQuickFlow
    };// end of new ActionListener(): alQuickFlow

    ActionListener alLossSum = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if ( aIpadDlg[LOSS_SUM_DLG] == null)
                aIpadDlg[LOSS_SUM_DLG] = new LossSumDlg(mainFrame, "Loss Summary");
            aIpadDlg[LOSS_SUM_DLG].show();
        }//end of actionPerformed():alLossSummary
    };// end of new ActionListener():alLossSummary

    ActionListener alNetFlow = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            if( ! canAccessEngine() ){ return; }
            SysConst.progress = 0;
            UpdateProgressThread t = new UpdateProgressThread(
                mainFrame.btnPanel, ButtonPanel.ENGN_MODE);
            t.start();

            String strUrl = WebConst.getNetflowURL() +
                "?WebPath=" + WebConst.getEngineWebPath() +
                "&PadPath=" + Sys.personalInfo.getTempPath().getPath() +
                "&Mode=1"+                      //mode 1 = NetFlow
                "&OverloadThreshold=100.0" +    //Not used by NetFlow
                "&UnderVoltageThreshold=0.95";  //Not used by NetFlow
            engineThread = new EngineThread(mainFrame, strUrl,
                EngineThread.ENG_NETFLOW);
            engineThread.start();
        }// end of actionPerformed() : alNetFlow
    };// end of new ActionListener() : alNetFlow

    ActionListener alShtCkt = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            if( ! canAccessEngine() ){ return; }

            SysConst.progress = 0;
            UpdateProgressThread t = new UpdateProgressThread(
                mainFrame.btnPanel, ButtonPanel.ENGN_MODE);
            t.start();

            String strUrl = WebConst.getNetflowURL() +
                "?WebPath=" + WebConst.getEngineWebPath() +
                "&PadPath=" + Sys.personalInfo.getTempPath().getPath() +
                "&Mode=2"+                        //mode 2 = short circuit
                "&OverloadThreshold=100.0" +      //Not used by short circuit
                "&UnderVoltageThreshold=0.95";    //Not used by short circuit
            engineThread = new EngineThread(mainFrame, strUrl,
                EngineThread.ENG_SHTCKT);
            engineThread.start();
        }// end of actionPerformed() : alShtCkt
    };// end of new ActionListener() : alShtCkt

    ActionListener alSecurity = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            if( ! canAccessEngine() ){ return; }
            SysConst.progress = 0;
            UpdateProgressThread t = new UpdateProgressThread(
                mainFrame.btnPanel, ButtonPanel.ENGN_MODE);
            t.start();

            String strUrl = WebConst.getNetflowURL() +
                "?WebPath=" + WebConst.getEngineWebPath() +
                "&PadPath=" + Sys.personalInfo.getTempPath().getPath() +
                "&Mode=3" + //mode 3 = security assessment
                "&OverloadThreshold=" + "100.0" +   //will be replaced a real para.
                "&UnderVoltageThreshold=" + "0.95"; //will be replaced a real para.
            engineThread = new EngineThread(mainFrame, strUrl,
                EngineThread.ENG_SECURITY);
            engineThread.start();
        }// end of actionPerformed() : alSecurity
    };// end of new ActionListener() : alSecurity

    ActionListener alDistRel = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if( ! canAccessEngine() ){ return; }

            SysConst.progress = 0;
            UpdateProgressThread t = new UpdateProgressThread(
                mainFrame.btnPanel, ButtonPanel.ENGN_MODE);
            t.start();
            int iBlockSag = (EngineProcessor.bDisableSag ? 1 : 0);
            // Set passed zone to the Zone for Root Cause Analysis
            EngineProcessor.dZoneToEngine = EngineProcessor.dRootCauseZone;
            String strUrl = WebConst.getDistrelURL() +
                "?WebPath=" + WebConst.getEngineWebPath() +
                "&PadPath=" + Sys.personalInfo.getTempPath().getPath() +
                "&Mode=1&Zone=" + EngineProcessor.getZoneAsEngineParamOld() +
                "&ID=0&P1=0&Blocksag=" + iBlockSag+
                "&TargetMAIFI=0&TargetSAIFI=0&TargetSAIDI=0";
            engineThread = new EngineThread(mainFrame, strUrl,
                EngineThread.ENG_DISTREL);
            engineThread.start();
        }// end of actionPerformed : alDistRel
    };// end of new ActionListener(): alDistRel

    ActionListener alNetRel = new ActionListener(){
        public void actionPerformed(ActionEvent evt){//throws Exception{
            if( ! canAccessEngine() ){ return; }

            SysConst.progress = 0;
            UpdateProgressThread t = new UpdateProgressThread(
                mainFrame.btnPanel, ButtonPanel.ENGN_MODE);
            t.start();

            int iPowerFlowBlocked = (EngineProcessor.bDisableCapFlow ? 1 : 0);
            int iDoubleContingencies=(EngineProcessor.bDisable2ndOrder ? 1 : 0);
            int iModelReduction = (EngineProcessor.bUseNetReduction ? 1 : 0);
            // Set passed zone to the Zone for Root Cause Analysis
            EngineProcessor.dZoneToEngine = EngineProcessor.dRootCauseZone;

            String strUrl = WebConst.getNetrelURL() +
                "?WebPath=" + WebConst.getEngineWebPath() +
                "&PadPath=" + Sys.personalInfo.getTempPath().getPath() +
                "&PowerFlowBlocked=" + iPowerFlowBlocked +
                "&DoubleContingenciesBlocked=" + iDoubleContingencies +
                "&Mode=1&Zone=" + EngineProcessor.getZoneAsEngineParamOld() +
                "&ModelReduction=" + iModelReduction;
            engineThread = new EngineThread(mainFrame, strUrl,
                EngineThread.ENG_NETREL);
            engineThread.start();
        }// end of actionPerformed : alNetRel
    };// end of new ActionListener(): alNetRel

    ActionListener alRelInd = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if( aIpadDlg[REL_IND_DLG] == null){
                aIpadDlg[REL_IND_DLG] = new RelIndDlg(mainFrame, "Reliability Indices");
            }
            aIpadDlg[REL_IND_DLG].show();
        }//end of actionPerformed():alRelInd
    };// end of new ActionListener():alRelInd

    ActionListener alReliaOptions = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if( aIpadDlg[RELIA_OPT_DLG] == null){
                aIpadDlg[RELIA_OPT_DLG] = new ReliabilityOptionsDlg(mainFrame,"Reliability Options");
            }
            aIpadDlg[RELIA_OPT_DLG].show();
        }//end of actionPerformed():alReliaOptions
    };// end of new ActionListener():alReliaOptions

    ActionListener alSensitivity = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if( aIpadDlg[SENSITIVITY_DLG] == null){
                aIpadDlg[SENSITIVITY_DLG] = new SensitivityDlg(mainFrame,"Sensitivity Analysis");
            }
            aIpadDlg[SENSITIVITY_DLG].show();
        }//end of actionPerformed():alSensitivity
    };// end of new ActionListener():alSensitivity

    ActionListener alRisk = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if( aIpadDlg[RISK_DLG] == null){
                aIpadDlg[RISK_DLG] = new RiskAnalysisDlg(mainFrame, "Risk Analysis");
            }
            aIpadDlg[RISK_DLG].show();
        }//end of actionPerformed():alRisk
    };// end of new ActionListener():alRisk

    ActionListener alOptSwt = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if( aIpadDlg[OPT_SWT_DLG] == null){
                aIpadDlg[OPT_SWT_DLG] = new OptSwtDlg(mainFrame,
                    "Optimize Switching Devices");
            }
            aIpadDlg[OPT_SWT_DLG].show();
        }//end of actionPerformed():alOptSwt
    };// end of new ActionListener():alOptSwt

    ActionListener alTerminate = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            String msg;
            if(engineThread!=null && engineThread.stopNow == false){
                engineThread.stopNow = true;
                msg="Analysis Terminated.";
            }else { msg="Invalid command. No engine is active now.";}
            JOptionPane.showMessageDialog(mainFrame, msg);
        }//end of actionPerformed():alTerminate
    };// end of new ActionListener():alTerminate

    /*==============================================================
    ActionListeners for menu item under "Results" menu
    ==============================================================*/
    ActionListener alDataSummary = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if ( aIpadDlg[DATA_SUM_DLG] == null)
                aIpadDlg[DATA_SUM_DLG] = new DataSumDlg(mainFrame,"Data Summary");
            aIpadDlg[DATA_SUM_DLG].show();
        }//end of actionPerformed():alDataSummary
    };// end of new ActionListener():alDataSummary

    ActionListener alCostSummary = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if ( aIpadDlg[COST_SUM_DLG] == null) {
                aIpadDlg[COST_SUM_DLG] = new CostSumDlg(mainFrame, "Cost Summary");
            }
            aIpadDlg[COST_SUM_DLG].show();
        } // end of actionPerformed():alCostSummary
    }; // end of new ActionListener():alCostSummary

    ActionListener alQuerySearch = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if( aIpadDlg[QUERY_DLG] == null){
                aIpadDlg[QUERY_DLG] = new QueryDlg(mainFrame, "Query Search");
            }
            aIpadDlg[QUERY_DLG].show();
            mainFrame.mainPanel.repaint();
        }//end of actionPerformed():alQuerySearch
    };// end of new ActionListener():alQuerySearch


    /*==============================================================
    ActionListeners for menu item under "Help" menu
    ==============================================================*/
    ActionListener alOnlineManual = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            try {
                URL url = new URL( WebConst.getManualURL() );
                mainFrame.getApplet().getAppletContext().showDocument(url,
                    "_blank");
            } catch(Exception e) {
                JOptionPane.showMessageDialog(mainFrame,
                    "Cannot load the user manual page.");
            }
        }//end of actionPerformed():alOnlineManual
    };// end of new ActionListener():alOnlineManual

    ActionListener alSubmitFeedback = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            try {
                mainFrame.showDocument(WebConst.getFeedbackURL(), "TOP");
            } catch(Exception e) {
                JOptionPane.showMessageDialog(mainFrame,
                    "Cannot load the user feedback page.");
            }
        }//end of actionPerformed():alSubmitFeedback
    };// end of new ActionListener():alSubmitFeedback

    ActionListener alAbout = new ActionListener(){
        public void actionPerformed(ActionEvent evt){
            if( aIpadDlg[ABOUT_DLG] ==null ) {
                aIpadDlg[ABOUT_DLG] = new AboutDlg(mainFrame);
            }
            aIpadDlg[ABOUT_DLG].show();
        }//end of actionPerformed():alAbout
    };// end of new ActionListener():alAbout

    /*=============================================
    Misc. methods
    =============================================*/

    public void initMenuItems(){
        undo.setEnabled( false );
        redo.setEnabled( false );
        loadBgImg.setEnabled(false);
        legend.setSelected( Sys.prjInfo.showLegend);
        scale.setSelected( Sys.prjInfo.showScale);
        gridLine.setSelected( Sys.prjInfo.showGridLine);
        text.setSelected( Sys.prjInfo.drawText);
        showNodes.setSelected( Sys.prjInfo.showNodes);
        freeze.setSelected( Sys.prjInfo.freeze );
        setShadeMenuText();
    }

    public void setUndoEnabled( boolean isEnabled){
        undo.setEnabled( isEnabled);
    }

    public void setRedoEnabled( boolean isEnabled){
        redo.setEnabled( isEnabled);
    }

    public void setLoadBgImageEnabled(boolean isEnabled){
        loadBgImg.setEnabled( isEnabled);
    }

    public void setShadeMenuText() {
        JMenuItem item = null;
        int iNumShadingOptions = Sys.prjInfo.storedShadingOptions.size();
        custShade.ensureCapacity(iNumShadingOptions);
        for (int i = 0; i < iNumShadingOptions; i++) {
            String sDesc = ((ShadingOption)Sys.prjInfo.storedShadingOptions.
                elementAt(i)).getDescription();
            if (i < custShade.size()) {
                // set menu item text
                item = (JMenuItem)custShade.elementAt(i);
                item.setText(sDesc);
            } else {
                // add additional menu item
                item = new JRadioButtonMenuItem(sDesc, false);
                item.addActionListener(alShadeOpt);
                custShade.add(item);
                shadingMenu.add(item);
                shadingGroup.add(item);
            }
            if (Sys.prjInfo.shadingCat == i)
                item.setSelected(true);
        }
        for (int i = custShade.size()-1; i >= iNumShadingOptions; i--) {
            // remove surplus menu item
            item = (JMenuItem)custShade.remove(i);
            shadingMenu.remove(item);
            shadingGroup.remove(item);
        }
        if (Sys.prjInfo.shadingCat == ProjectInfo.SHADE_NONE)
            noShading.setSelected(true);
        else if (Sys.prjInfo.shadingCat == ProjectInfo.SHADE_BY_ZONE)
            shadeByZone.setSelected(true);
        else if (Sys.prjInfo.shadingCat == ProjectInfo.SHADE_BY_STUDY_AREA)
            shadeByStudyArea.setSelected(true);
        else if (Sys.prjInfo.shadingCat == ProjectInfo.SHADE_BY_NOM_VOLTAGE)
            shadeByNomVoltage.setSelected(true);
    }

    public void setCurrentShadingOption(int cat) {
        Sys.prjInfo.shadingCat = cat;
        if (cat >= 0 && cat < Sys.prjInfo.storedShadingOptions.size()) {
            // Just a shortcut
            ShadingOption so = Sys.prjInfo.currentShadingOption;
            so.copyFrom((ShadingOption)Sys.prjInfo.storedShadingOptions.
                elementAt(cat));

            if (so.getAutoScale()) {
                Sys.Histogram hist = new Sys.Histogram();
                // the number of bins is chosen arbitrarily
                hist.setBinCount(100);
                hist.setField(so.getIndex(), so.getIsResult());
                // determine automatically start and end values for a histogram
                // over the whole range
                hist.findStartEnd();
                // build histogram
                hist.buildHistogram();

                // determine start value
                // dTarget is the number of elements we want to find
                double dTarget =
                    (so.getPercentBelow() * hist.getTotalBin()) / 100;
                double dSum = hist.getBelowBin();
                double dValue;
                if (dSum >= dTarget) {
                    // since the below bin is always empty this only happens if
                    // getTotalBin equals zero
                    dValue = hist.getStart();
                } else {
                    int iBin = -1;
                    do {
                        iBin++;
                        dSum += hist.getBin(iBin);
                    } while (dSum < dTarget && iBin < hist.getBinCount()-1);
                    if (dSum < dTarget) {
                        // to less elements are outside the above bin
                        dValue = hist.getStart();
                    } else {
                        // linear interpolation of the start value according to
                        // the law of similar triangles:
                        //
                        //  UpperLimit - Value     Size
                        // -------------------- = ------  =>
                        //     Sum - Target        Bin
                        //
                        // UpperLimit - Value = (Sum - Target) * Size / Bin  =>
                        //
                        dValue = hist.getUpperBinLimit(iBin) - (dSum-dTarget) *
                            hist.getBinSize() / hist.getBin(iBin);
                    }
                }
                // set start value rounded to one decimal places
                so.setStartValue(Math.floor(dValue * 10.0 + 0.5) / 10.0);

                // determine end value
                dTarget = (so.getPercentAbove() * hist.getTotalBin()) / 100;
                dSum = hist.getAboveBin();
                if (dSum >= dTarget) {
                    // this happends if either enough elements are inside the
                    // above bin or getTotalBin equals zero
                    dValue = hist.getEnd();
                } else {
                    int iBin = hist.getBinCount();
                    do {
                        iBin--;
                        dSum += hist.getBin(iBin);
                        // we do not need to check whether iBin > 0 since the
                        // below bin is always empty and therefore all elements
                        // are inside the above bin or any regular bin
                    } while (dSum < dTarget);
                    // linear interpolation of the end value
                    dValue = hist.getLowerBinLimit(iBin) +
                        (dSum-dTarget) * hist.getBinSize() / hist.getBin(iBin);
                }
                // set end value rounded to one decimal places
                so.setEndValue(Math.floor(dValue * 10.0 + 0.5) / 10.0);
            }
        } else if (cat == ProjectInfo.SHADE_BY_NOM_VOLTAGE) {
            Sys.assignVoltageLevelToAllElements(false);
        }
    }

    public void setRecentPrjMenuText() {
        for (int i = 0; i < PersonalInfo.MAX_RECENT_PRJ; i++) {
            File f = Sys.personalInfo.getRecentProject(i);
            if (f == null) {
                // No more recent projects
                break;
            }
            if (recentPrjs[i].getText().length() == 0) {
                // Things will be inserted above the exit separator
                int index = fileMenu.getMenuComponentCount() - 2;
                if (i == 0) {
                    // There was no recent project before, we have to insert an
                    // additional separator above the exit separator
                    fileMenu.insertSeparator(index++);
                }
                // There haven't been so many recent projects before,
                // we have to insert recentPrjs[i] above the exit separator
                fileMenu.insert(recentPrjs[i], index);
            }
            // Update menu item text
            String sFilename = f.getPath();
            // check whether the filename is too long to be displayed completely
            // note: the maximum length of 64 is chosen arbitrary
            final int TooLong = 64;
            if (sFilename.length() > TooLong) {
                // determine beginLength as the first separator after prefix
                // (3 should cover all prefixes)
                int beginLength = sFilename.indexOf(f.separatorChar, 3) + 1;
                // determine smallest endIndex, so that
                // beginLength + 3 + (sFilename.length() - endIndex) == TooLong
                int endIndex = beginLength + 3 + sFilename.length() - TooLong;
                // try to find next separator
                int endTry = sFilename.indexOf(f.separatorChar, endIndex);
                if (endTry >= 0)
                    endIndex = endTry;
                // else
                //   the user have to live with a uncomplete file name

                // built shorter filename
                sFilename = sFilename.substring(0, beginLength) + "..." +
                    sFilename.substring(endIndex);
                // display full filename in tooltip
                recentPrjs[i].setToolTipText(f.getPath());
            } else {
                // reset tooltip
                recentPrjs[i].setToolTipText(null);
            }
            recentPrjs[i].setText("" + (i+1) + " " + sFilename);
        }
    }

    /*==============================================================
    Open/save project methods
    ==============================================================*/
    void newProject() {
        // prepare system
        Container thePane = mainFrame.getContentPane();
        thePane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

        mainFrame.statusBar.clearText();
        mainFrame.menuBar.disposeAllIpadDlgs();
        mainFrame.menuBar.resetUndoRedoQueue();
        if( Sys.prjInfo.iActiveLayer<0) { mainFrame.btnPanel.enterForeGroundMode(); }
        Sys.reset();
        Templates.reset();

        // open default template library
        try {
            String fileName = Sys.personalInfo.getGlobalDefaultTemplateFile();
            if( fileName.toLowerCase().endsWith(".pad") ){
                BinaryFileAccessor bfa = new BinaryFileAccessor();
                bfa.initProject( fileName );
            }
            else if( fileName.toLowerCase().endsWith(".mdb") ){
                DBAccessor dba = new DBAccessor();
                dba.initProject( fileName );
            } else {
                JOptionPane.showMessageDialog(mainFrame,
                    "No global default file found.\n");
            }
        } catch (Exception e) {
            JOptionPane.showMessageDialog(mainFrame,
                "Error Occured @ newProject:\n"+e);
        }

        // post processing
        mainFrame.statusBar.clearText();
        prjFile = null;
        mainFrame.setTitle(" Project1 [New Project]");
        initMenuItems();
        mainFrame.mainPanel.setNeedRedraw(true);
        mainFrame.mainPanel.repaint();
        thePane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    }//end of newProject();

    boolean openProject(File f) {
        boolean bOldVersion = false;

        // check whether file can be read
        if (!f.canRead()) {
            JOptionPane.showMessageDialog(mainFrame, "The file '" + f.getPath()+
                "' can not be read or does not exist.", "Open",
                JOptionPane.ERROR_MESSAGE);
            return false;
        }

        // get file name
        prjFile = f;
        String sTitle = " " + prjFile.getName();
        if (!f.canWrite())
            sTitle  += " (Read-Only)";
        mainFrame.setTitle(sTitle);

        // prepare system
        UpdateProgressThread t = new UpdateProgressThread(
            mainFrame.btnPanel, ButtonPanel.OPEN_MODE);
        t.start();

        Container thePane = mainFrame.getContentPane();
        thePane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

        mainFrame.statusBar.clearText();
        mainFrame.menuBar.disposeAllIpadDlgs();
        mainFrame.menuBar.resetUndoRedoQueue();
        if( Sys.prjInfo.iActiveLayer<0) { mainFrame.btnPanel.enterForeGroundMode(); }
        Sys.reset();
        Templates.reset();

        // open file
        try {
            if( prjFile.getPath().endsWith(".pad") ) {
                BinaryFileAccessor bfa = new BinaryFileAccessor();
                bfa.loadFromFile(prjFile.getPath());
            } else if(prjFile.getPath().endsWith(".mdb") ) {
                DBAccessor dba = new DBAccessor();
                if (dba.loadDataThruQuery( prjFile.getPath())) {
                    JOptionPane.showMessageDialog(mainFrame,
                        "Some elements may have unknown types", "Open",
                        JOptionPane.WARNING_MESSAGE);
                }
                bOldVersion = dba.getIsOldStyleSystem();
            } else {
                JOptionPane.showMessageDialog(mainFrame,
                    "Only support *.mdb and *.pad format.", "Open",
                    JOptionPane.ERROR_MESSAGE);
                return false;
            }

            // Reset current shading
            setCurrentShadingOption(Sys.prjInfo.shadingCat);
            zoomAll();           // zoom all will call repaint()
            initMenuItems();

            if ( bOldVersion == true) {
                thePane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                if (JOptionPane.showConfirmDialog(mainFrame,
                        "This is an old version system without system " +
                        "connectivity.\nDo you want to run Connectivity " +
                        "which may take a few minutes?", "Connectivity",
                        JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
                    thePane.setCursor(Cursor.getPredefinedCursor(
                        Cursor.WAIT_CURSOR));
                    t = new UpdateProgressThread(mainFrame.btnPanel,
                        ButtonPanel.CONN_MODE);
                    t.start();
                    Sys.findSysConn();
                }
            }

            thePane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            Vector vUnsyncElemList = Templates.findUnsyncElem();
            //Vector noTmpltElemList= Templates.findNoTmpltElem();
            if( vUnsyncElemList.size() != 0) {
                for(int i=0; i<vUnsyncElemList.size();i++) {
                    Sys.addElemToSelection( (AbsElem) vUnsyncElemList.get(i));
                }

                if( aIpadDlg[LOG_DLG] == null ) {
                    aIpadDlg[LOG_DLG] = new LogDlg(mainFrame,"Log Window");
                }
                aIpadDlg[LOG_DLG].show();
                ((LogDlg)aIpadDlg[LOG_DLG]).putData( vUnsyncElemList );
                //((LogDlg)aIpadDlg[LOG_DLG]).putData( noTmpltElemList );

                thePane.setCursor(Cursor.getPredefinedCursor(
                    Cursor.DEFAULT_CURSOR));
                if (JOptionPane.showConfirmDialog(aIpadDlg[LOG_DLG],
                        "Some components are not synchronized with Default " +
                        "Templates.\nDo you want to synchronize them now?",
                        "Synchronization", JOptionPane.YES_NO_OPTION,
                        JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) {
                    thePane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                    Templates.syncElemInVector( vUnsyncElemList );
                }
            }//end of if ( there are unsynchronized components)
        } catch (Exception e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(mainFrame,
                "Error while opening file '" + prjFile.getPath() + "':\n" +
                e.getMessage(), "Open", JOptionPane.ERROR_MESSAGE);
            return false;
        } finally {
            // Make sure that the progress bar shuts down
            t.interrupt();
            thePane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        }

        mainFrame.mainPanel.setNeedRedraw(true);
        mainFrame.mainPanel.repaint();

        // add to recent projects if everything was okay
        Sys.personalInfo.addRecentProject(prjFile);
        setRecentPrjMenuText();

        return true;
    }//end of openProject();

    void saveProject() {
        UpdateProgressThread t = new UpdateProgressThread(
            mainFrame.btnPanel, ButtonPanel.SAVE_MODE);
        t.start();

        Container thePane = mainFrame.getContentPane();
        thePane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

        try {
            // check existence
//            if (prjFile.getPath().endsWith(".mdb") ){ //&& !prjFile.exists()) {
//                if( prjFile.exists() ) { prjFile.delete(); }
//                Sys.personalInfo.copyGlobalDefaultTemplateFile(prjFile);
//                DBAccessor dba = new DBAccessor();
//                dba.cleanGlobalTemplate(prjFile.getPath()); //preventative redundency
//                dba.saveDataThruQuery(prjFile.getPath());
//            } else
            if( prjFile.getPath().endsWith(".pad") ){
                if( prjFile.exists() ) { prjFile.delete(); }
                BinaryFileAccessor bfa = new BinaryFileAccessor();
                bfa.saveToFile(prjFile.getPath());
            }
        } catch (Exception e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(mainFrame,
                "Error while saving file '" + prjFile.getPath() + "':\n" +
                e.getMessage(), "Save", JOptionPane.ERROR_MESSAGE);
        } finally {
            // Make sure that the progress bar shuts down
            t.interrupt();
            thePane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        }
    }

    /*==============================================================
    Export/Import All Component Data into/from CSV files
    ==============================================================*/
    void exportAllData( File f) throws IOException{
        // check whether file already exists
        if( !f.exists() ){ f.createNewFile();}
        else {
            if( JOptionPane.YES_OPTION != JOptionPane.showConfirmDialog(mainFrame,
            "File already exists. Do you want to overwrite it?", "Confirmation",
            JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) )
                return;
        }

        //check whether it is writable or not
        if (!f.canWrite() ) {
        JOptionPane.showMessageDialog(mainFrame, "The file '" + f.getPath()+
            "' can not be write or does not exist.", "Open",
            JOptionPane.ERROR_MESSAGE);
                return;
        }

        BufferedWriter bw = new BufferedWriter(new FileWriter(f));
        /* Original
        bw.write("\"Component\", \"Please don't change the format of this file.\"\r\n");
        bw.write("\"Note 1: Type will not be updated. It is for reference only.\"\r\n");
        bw.write("\"Note 2: Please do not use comma in Type or Name field.\"\r\n");
        bw.write("\"ID\",\"Name\",\"Type\",");

        for(int k=1; k<SysConst.ssDataField.length; k++){ //starts from 1!!!
            bw.write("\""+ SysConst.ssDataField[k] +"\",");
            bw.write("\"Default:"+ SysConst.ssDataField[k] + "\"");
            if( k != SysConst.ssDataField.length -1) { bw.write(","); }
        }
        */
        //addd by Yanli
        bw.write("%% generator data \r\n");
        bw.write("%    ");
        for(int k=52; k<SysConst.ssDataField.length; k++){ 
            bw.write(SysConst.ssDataField[k]  );
            if( k != SysConst.ssDataField.length -1) { bw.write("  "); }
        }
        bw.write("\r\ngen = [");
        bw.write("\r\n");

        int sz = Sys.elemList.size();
        AbsElem elem;
        AbsElemGeom geom;
        double val;
        int flag;
        for(int i=0;i<sz;i++){
            elem = (AbsElem) Sys.elemList.elementAt(i);
            geom = elem.getElemGeomObj();
            /* Yanli
            bw.write( (i+1) +","); //external id = internal id + 1
            bw.write( geom.getName() +",");
            bw.write( elem.getStringForType() +",");
            */
            for(int k=52; k<SysConst.ssDataField.length; k++){ //starts from 1!!!
                val = elem.getData( SysConst.mapDataIndexFromDisplayToValue(k) );
                //flag = elem.getFlag( SysConst.mapDataIndexFromDisplayToValue(k) );
                bw.write( val +" ");
                //bw.write( flag + "" );
                //if( k != SysConst.ssDataField.length-1) { bw.write(","); }
                if( k != SysConst.ssDataField.length-1) { bw.write("  "); }
            }
            bw.write(";\r\n");
        }
        bw.write("]");
        bw.close();

        Sys.personalInfo.execExcel( f.getPath());
    }//end of exportAllData( File)

    void importAllData( File f) throws IOException{
        AbsElem elem;
        AbsElemGeom geom;
        double val;
        int flag;
        String str, str2;
        int sz, cntr, id;
        StringTokenizer strToken;
        BufferedReader br;

        // check whether file can be read
        if (!f.canRead() ) {
        JOptionPane.showMessageDialog(mainFrame, "The file '" + f.getPath()+
            "' can not be read or does not exist.", "Open",
            JOptionPane.ERROR_MESSAGE);
                return;
        }

        sz = Sys.elemList.size();
        br = new BufferedReader(new FileReader(f));
//        str = br.readLine();  //title
//        str = br.readLine();  //note 1
//        str = br.readLine();  //note 2
//        str = br.readLine();  //column names

        str = br.readLine();  //first line
        cntr = 0;
        while ( str!=null && str.trim().compareTo("")!=0 ) { //&& cntr < sz ){
            strToken = new StringTokenizer( str, ",");
            try{
              id = Integer.parseInt( strToken.nextToken() );
            }catch (Exception e) {
              str = br.readLine();
              //no need to increase cntr
              continue;
            }
            if( id < 1 || id > Sys.elemList.size() ){
                JOptionPane.showMessageDialog(mainFrame,
                    "Error: ID " + id + " is out of bound");
                return;
            }

            elem = (AbsElem) Sys.elemList.get( id-1 );
            geom = elem.getElemGeomObj();

            str2 = strToken.nextToken();
            geom.setName( str2 );

            str2 = strToken.nextToken();
            //type will not be updated

            for(int k=1; k<SysConst.ssDataField.length; k++){ //starts from 1!!!
                val = Double.parseDouble( strToken.nextToken() );
                flag = Integer.parseInt( strToken.nextToken());
                elem.setData( SysConst.mapDataIndexFromDisplayToValue(k), val );
                elem.setFlag( SysConst.mapDataIndexFromDisplayToValue(k), flag );
            }

            str = br.readLine();
            cntr++;
        }
        br.close();
    }//end of

    /*==============================================================
    Default/Package methods

    ==============================================================*/

    /**
     * To show elem info dialog to edit info
     * For Background layer, show the same EditBgLineDlg regardless of
     * the # of elements;
     * For foreground components, show CompInfoDlg if only ONE comp selected,
     * and show DataModifyDlg if multiple (>=2) comp selected
     *
     * showElemInfoForAnyCase will be called when
     *    1. right mouse double clicked
     *    2. popup menu Component Infomation is clicked
     *    3. menu Component Information is clicked
     */
    void showElemInfoForAnyCase(){
        if (Sys.selectedList.size() <= 0) {
            JOptionPane.showMessageDialog(mainFrame,
                "Please select a component");
        } else if (Sys.prjInfo.iActiveLayer == Sys.prjInfo.BG_IMAGE_LAYER) {
            showBgImageInfoDlg();
        } else if (Sys.prjInfo.iActiveLayer == Sys.prjInfo.BG_LINE_LAYER) {
            showBgLineInfoDlg();
        } else if (Sys.selectedList.size() == 1) {
            AbsElem elem = (AbsElem) Sys.selectedList.elementAt(0);
            if ( aIpadDlg[ELEM_INFO_DLG] == null){
                aIpadDlg[ELEM_INFO_DLG] = new ElemInfoDlg(mainFrame,
                    "Component Information", false, elem); //non-modal
            } else {
                ((ElemInfoDlg)aIpadDlg[ELEM_INFO_DLG]).setCurrentElem(elem);
            }
            aIpadDlg[ELEM_INFO_DLG].show();
        } else {
            if ( aIpadDlg[DATA_MODIFY_DLG] == null)
                aIpadDlg[DATA_MODIFY_DLG] = new DataModifyDlg(mainFrame);
            ((DataModifyDlg)aIpadDlg[DATA_MODIFY_DLG]).setArea(
                Zone.SELECTED_AREA);
            aIpadDlg[DATA_MODIFY_DLG].show();
        }
    }

    void showBgImageInfoDlg(){
        if ( aIpadDlg[EDIT_BGIMAGE_DLG] == null){
            aIpadDlg[EDIT_BGIMAGE_DLG] = new EditBgImageDlg(
                mainFrame, "Back Ground Image");
        }
        aIpadDlg[EDIT_BGIMAGE_DLG].show();
    }//end of showBgImageDlg();

    void showBgLineInfoDlg(){
        if ( aIpadDlg[EDIT_BGLINE_DLG] == null){
            aIpadDlg[EDIT_BGLINE_DLG] = new EditBgLineDlg(
                mainFrame, "Back Ground Line");
        }
        aIpadDlg[EDIT_BGLINE_DLG].show();
    }//end of showBgLineInfoDlg();

    void showOptionsDlg(int activeTab) {
        if ( aIpadDlg[ELEM_INFO_DLG] != null && aIpadDlg[ELEM_INFO_DLG].isVisible()) {
            // When an option(like scale) changes, the length of line will
            // change. However, this won't be reflected in the elemInfoDlg.
            // If making it invisible, then it will brings back the updated
            // length.
            aIpadDlg[ELEM_INFO_DLG].setVisible(false);
        }

        if ( aIpadDlg[OPTIONS_DLG] == null) {
            aIpadDlg[OPTIONS_DLG] = new OptionsDlg(mainFrame, "Options", activeTab);
        } else {
            ((OptionsDlg)aIpadDlg[OPTIONS_DLG]).setActiveTab(activeTab);
        }
        aIpadDlg[OPTIONS_DLG].show();
    }

    /*====================================================
     * this will be called when
     * 1. menu Edit Legend is cliced
     * 2. left mouse double clicked in Legend Area
            =(10,10, 150,100)based on ViewPort Origin
    ====================================================*/
    void showEditShadingDlg(){
        if ( aIpadDlg[EDIT_SHADING_DLG] == null) {
            aIpadDlg[EDIT_SHADING_DLG] = new EditShadingDlg(mainFrame, "Edit Shading Options");
        } else {
            ((EditShadingDlg)aIpadDlg[EDIT_SHADING_DLG]).updateContent();
        }
        aIpadDlg[EDIT_SHADING_DLG].show();
    }

    /**
     * If this is called by users interaction, this is redundent for
     * activeTempDlg,editTempDlg, and aboutDlg
     * since they are modual dialogs which must be closed(hidden)
     * before users can click on any menu item.
     */
    void hideAllIpadDlgs(){
        for(int i=0; i< NUM_IPAD_DLGS; i++){
            if( aIpadDlg[i] != null ) { aIpadDlg[i].hide(); }
        }
    }

    /**
     * It's safe and clean if disposing those dlgs when loading a new project.
     * elemInfoDlg is not disposed since it is a heavy-loaded dlg and takes
     * lots of CPU time to create this dialog.
     * So, it is always hidden.  But, information in ElemInfoDlg is always
     * updated whenever this dlg is activated.
     */
    void disposeAllIpadDlgs(){
        for(int i=0; i< NUM_IPAD_DLGS; i++){
            if( aIpadDlg[i] != null ){
                if( i== ELEM_INFO_DLG ) { aIpadDlg[i].hide(); }
                else { aIpadDlg[i].dispose(); aIpadDlg[i]=null; }
            }
        }
     }

     private void resetUndoRedoQueue(){
        this.editActionQueueBgImage.reset();
        this.editActionQueueBgLine.reset();
        this.editActionQueueFg.reset();
        this.activeQueue = this.editActionQueueFg;
     }


    /***************************************************
    Constructors
    ***************************************************/
    public MainMenuBar() {
        try {
            setMenus();
            setActionListeners();
            fileChooser = new JFileChooser();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    private void setMenus() {
        fileMenu = new JMenu("File");
            this.add(fileMenu);
            fileMenu.setMnemonic('F');
            newPrj = new JMenuItem("New Project");
                newPrj.setMnemonic('N');
                newPrj.setAccelerator(
                    KeyStroke.getKeyStroke(KeyEvent.VK_N, Event.CTRL_MASK));
                fileMenu.add(newPrj);
            openPrj = new JMenuItem("Open Project...");
                openPrj.setMnemonic('O');
                openPrj.setAccelerator(
                    KeyStroke.getKeyStroke(KeyEvent.VK_O, Event.CTRL_MASK));
                fileMenu.add(openPrj);
            importZones = new JMenuItem("Import Zones...");
                importZones.setMnemonic('I');
                fileMenu.add(importZones);
            fileMenu.addSeparator();
            savePrj = new JMenuItem("Save Project");
                savePrj.setMnemonic('S');
                savePrj.setAccelerator(
                    KeyStroke.getKeyStroke(KeyEvent.VK_S, Event.CTRL_MASK));
                fileMenu.add(savePrj);
            savePrjAs = new JMenuItem("Save Project As...");
                savePrjAs.setMnemonic('A');
                fileMenu.add(savePrjAs);
            exportData = new JMenuItem("Output Data & Results...");
                exportData.setMnemonic('D');
                fileMenu.add(exportData);
            fileMenu.addSeparator();
            loadDftLib = new JMenuItem("Load Default Library...");
                loadDftLib.setMnemonic('L');
                fileMenu.add(loadDftLib);
            loadBgImg = new JMenuItem("Load Background Image...");
                loadBgImg.setMnemonic('B');
                fileMenu.add(loadBgImg);
            // separator will be inserted in setRecentPrjMenuText()
            for (int i = 0; i < PersonalInfo.MAX_RECENT_PRJ; i++) {
                recentPrjs[i] = new JMenuItem("");
                // This only works well for i <= 8
                recentPrjs[i].setMnemonic('1'+i);
                // recentPrjs[i] will be inserted in setRecentPrjMenuText()
            }
            fileMenu.addSeparator();
            exit = new JMenuItem("Exit Program");
                exit.setMnemonic('X');
                fileMenu.add(exit);
            setRecentPrjMenuText();

        editMenu = new JMenu("Edit");
            this.add(editMenu);
            editMenu.setMnemonic('E');
            undo = new JMenuItem("Undo");
                undo.setMnemonic('U');
                undo.setAccelerator(
                    KeyStroke.getKeyStroke(KeyEvent.VK_Z, Event.CTRL_MASK));
                undo.setEnabled(false);
                editMenu.add(undo);
            redo = new JMenuItem("Redo");
                redo.setMnemonic('O');
                redo.setAccelerator(
                    KeyStroke.getKeyStroke(KeyEvent.VK_Y, Event.CTRL_MASK));
                redo.setEnabled(false);
                editMenu.add(redo);
            editMenu.addSeparator();
            rotate = new JMenuItem("Rotate");
                rotate.setMnemonic('R');
                rotate.setAccelerator(
                    KeyStroke.getKeyStroke(KeyEvent.VK_R, Event.CTRL_MASK));
                editMenu.add(rotate);
            toggle = new JMenuItem("Toggle");
                toggle.setMnemonic('T');
                toggle.setAccelerator(
                    KeyStroke.getKeyStroke(KeyEvent.VK_T, Event.CTRL_MASK));
                editMenu.add(toggle);
            delete = new JMenuItem("Delete");
                delete.setMnemonic('D');
                delete.setAccelerator(
                    KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
                editMenu.add(delete);
            copy = new JMenuItem("Copy");
                copy.setMnemonic('C');
                copy.setAccelerator(
                    KeyStroke.getKeyStroke(KeyEvent.VK_C, Event.CTRL_MASK));
                editMenu.add(copy);
            editMenu.addSeparator();
            cmpInfo = new JMenuItem("Component Information...");
                cmpInfo.setMnemonic('I');
                cmpInfo.setAccelerator(
                    KeyStroke.getKeyStroke(KeyEvent.VK_E, Event.CTRL_MASK));
                editMenu.add(cmpInfo);
            if (SysConst.DEBUG_MODE > 0) {
                cmpInfoDebug = new JMenuItem("Connectivity...");
                    cmpInfoDebug.setMnemonic('N');
                    editMenu.add(cmpInfoDebug);
            }
            editMenu.addSeparator();
            findCmp = new JMenuItem("Find Component...");
                findCmp.setMnemonic('F');
                findCmp.setAccelerator(
                    KeyStroke.getKeyStroke(KeyEvent.VK_F, Event.CTRL_MASK));
                editMenu.add(findCmp);
            select = new JMenu("Select");
                select.setMnemonic('S');
                editMenu.add(select);
                selectToSource = new JMenuItem("Trace to Source");
                    selectToSource.setMnemonic('T');
                    selectToSource.setAccelerator(
                        KeyStroke.getKeyStroke(KeyEvent.VK_U, Event.CTRL_MASK));
                    select.add(selectToSource);
                selectAwayFromSource = new JMenuItem("Trace from Source");
                    selectAwayFromSource.setMnemonic('W');
                    selectAwayFromSource.setAccelerator(
                        KeyStroke.getKeyStroke(KeyEvent.VK_D, Event.CTRL_MASK));
                    select.add(selectAwayFromSource);
                selectDeenergized = new JMenuItem("Deenergized Components");
                    selectDeenergized.setMnemonic('G');
                    selectDeenergized.setAccelerator(
                        KeyStroke.getKeyStroke(KeyEvent.VK_G, Event.CTRL_MASK));
                    select.add(selectDeenergized);
                selectStudyArea = new JMenuItem("Study Area");
                    selectStudyArea.setMnemonic('Y');
                    select.add(selectStudyArea);
                selectZone = new JMenuItem("Zone...");
                    selectZone.setMnemonic('Z');
                    select.add(selectZone);
                selectVoltageLevel = new JMenuItem("Nominal Voltage...");
                    selectVoltageLevel.setMnemonic('V');
                    select.add(selectVoltageLevel);
                selectOpenSwt = new JMenuItem("Open Points");
                    selectOpenSwt.setMnemonic('O');
                    select.add(selectOpenSwt);
                invertSelection = new JMenuItem("Invert Selection");
                    invertSelection.setMnemonic('I');
                    select.add(invertSelection);
                selectAll = new JMenuItem("All");
                    selectAll.setMnemonic('A');
                    selectAll.setAccelerator(
                        KeyStroke.getKeyStroke(KeyEvent.VK_A, Event.CTRL_MASK));
                    select.add(selectAll);
                select.addSeparator();
                commonZone = new JMenuItem("Common Zone");
                    commonZone.setMnemonic('C');
                    select.add(commonZone);
                commonDefaultTemplate = new JMenuItem("Common Default Templates");
                    commonDefaultTemplate.setMnemonic('P');
                    select.add(commonDefaultTemplate);
                commonName = new JMenuItem("Common Name");
                    commonName.setMnemonic('N');
                    select.add(commonName);
                commonPhase = new JMenuItem("Common Phase");
                    commonPhase.setMnemonic('P');
                    select.add(commonPhase);
                commonVoltageLevel = new JMenuItem("Common Nominal Voltage");
                    commonVoltageLevel.setMnemonic('L');
                    select.add(commonVoltageLevel);
            editMenu.addSeparator();
            activeTemp = new JMenuItem("Active Template...");
                activeTemp.setMnemonic('A');
                editMenu.add(activeTemp);
            dftTemp = new JMenuItem("Edit Default Template...");
                dftTemp.setMnemonic('P');
                editMenu.add(dftTemp);
            editMenu.addSeparator();
            studyArea = new JMenu("Study Area");
                studyArea.setMnemonic('Y');
                editMenu.add(studyArea);
                setSelectionToStudyArea = new JMenuItem("Set Selection to Study Area");
                    setSelectionToStudyArea.setMnemonic('S');
                    setSelectionToStudyArea.setAccelerator(
                        KeyStroke.getKeyStroke(KeyEvent.VK_F1, Event.SHIFT_MASK));
                    studyArea.add(setSelectionToStudyArea);
                addSelectionToStudyArea = new JMenuItem("Add Selection to Study Area");
                    addSelectionToStudyArea.setMnemonic('A');
                    addSelectionToStudyArea.setAccelerator(
                        KeyStroke.getKeyStroke(KeyEvent.VK_F2, Event.SHIFT_MASK));
                    studyArea.add(addSelectionToStudyArea);
                removeSelectionFromStudyArea = new JMenuItem("Remove Selection from Study Area");
                    removeSelectionFromStudyArea.setMnemonic('R');
                    removeSelectionFromStudyArea.setAccelerator(
                        KeyStroke.getKeyStroke(KeyEvent.VK_F3, Event.SHIFT_MASK));
                    studyArea.add(removeSelectionFromStudyArea);
                clearStudyArea = new JMenuItem("Clear Study Area");
                    clearStudyArea.setMnemonic('C');
                    clearStudyArea.setAccelerator(
                        KeyStroke.getKeyStroke(KeyEvent.VK_F4, Event.SHIFT_MASK));
                    studyArea.add(clearStudyArea);
            group = new JMenu("Group");
                group.setMnemonic('G');
                editMenu.add(group);
                ungroup = new JMenuItem("Ungroup");
                    ungroup.setMnemonic('U');
                    group.add(ungroup);
            lineAndCable = new JMenu("Line/Cable");
                lineAndCable.setMnemonic('L');
                editMenu.add(lineAndCable);
                combineSelectedSections = new JMenuItem("Combine Selected Sections");
                    combineSelectedSections.setMnemonic('C');
                    combineSelectedSections.setAccelerator(KeyStroke.getKeyStroke(
                        KeyEvent.VK_F3, Event.SHIFT_MASK+Event.CTRL_MASK));
                    lineAndCable.add(combineSelectedSections);
                insertNode = new JMenuItem("Insert Node");
                    insertNode.setMnemonic('I');
                    insertNode.setAccelerator(KeyStroke.getKeyStroke(
                        KeyEvent.VK_F4, Event.SHIFT_MASK+Event.CTRL_MASK));
                    lineAndCable.add(insertNode);

        viewMenu = new JMenu("View");
            viewMenu.setMnemonic('V');
            this.add(viewMenu);
            legend = new JCheckBoxMenuItem("Legend");
                legend.setMnemonic('L');
                viewMenu.add(legend);
            scale = new JCheckBoxMenuItem("Scale");
                scale.setMnemonic('S');
                viewMenu.add(scale);
            gridLine = new JCheckBoxMenuItem("Grid Line");
                gridLine.setMnemonic('G');
                viewMenu.add(gridLine);
            text = new JCheckBoxMenuItem("Text");
                text.setMnemonic('T');
                text.setSelected(Sys.prjInfo.drawText);
                viewMenu.add(text);
            viewMenu.addSeparator();
            showNodes = new JCheckBoxMenuItem("Show Nodes");
                showNodes.setMnemonic('N');
                showNodes.setAccelerator(
                    KeyStroke.getKeyStroke(KeyEvent.VK_F6, 0));
                viewMenu.add(showNodes);
            viewMenu.addSeparator();
            highLights = new JMenu("Highlights");
                highLights.setMnemonic('H');
                viewMenu.add(highLights);
                highLightAll = new JMenuItem("Highlight All");
                    highLightAll.setMnemonic('A');
                    highLights.add(highLightAll);
                highLightNone = new JMenuItem("Highlight None");
                    highLightNone.setMnemonic('N');
                    highLights.add(highLightNone);
                highLights.addSeparator();
                highLightSelected = new JCheckBoxMenuItem("Selected Components (yellow)");
                    highLightSelected.setMnemonic('S');
                    highLights.add(highLightSelected);
                highLightOpenPoints = new JCheckBoxMenuItem("Open Points (red)");
                    highLightOpenPoints.setMnemonic('O');
                    highLights.add(highLightOpenPoints);
                highLightProtection = new JCheckBoxMenuItem("Protection Points (magenta)");
                    highLightProtection.setMnemonic('P');
                    highLights.add(highLightProtection);
                highLightSect = new JCheckBoxMenuItem("Sectionalizing Points (blue)");
                    highLightSect.setMnemonic('C');
                    highLights.add(highLightSect);
            viewMenu.addSeparator();
            layerMngr = new JMenuItem("Layer Manager...");
                layerMngr.setMnemonic('L');
                layerMngr.setAccelerator(
                    KeyStroke.getKeyStroke(KeyEvent.VK_F7, 0));
                viewMenu.add(layerMngr);
            // satelliteView = new JMenuItem("Satellite View");
                // viewMenu.add(satelliteView);
            viewMenu.addSeparator();
            freeze = new JCheckBoxMenuItem("Freeze System");
                freeze.setMnemonic('F');
                viewMenu.add(freeze);
            viewMenu.addSeparator();
            refresh = new JMenuItem("Refresh Screen");
                refresh.setMnemonic('R');
                refresh.setAccelerator(
                    KeyStroke.getKeyStroke(KeyEvent.VK_F12, 0));
                viewMenu.add(refresh);

        shadingMenu = new JMenu("Shading");
            shadingMenu.setMnemonic('S');
            this.add(shadingMenu);
            shadingGroup = new ButtonGroup();
            noShading = new JRadioButtonMenuItem("No Shading", true);
                noShading.setMnemonic('N');
                shadingMenu.add(noShading);
                shadingGroup.add(noShading);
            shadeByZone = new JRadioButtonMenuItem("Shade by Zone", false);
                shadeByZone.setMnemonic('Z');
                shadingMenu.add(shadeByZone);
                shadingGroup.add(shadeByZone);
            shadeByStudyArea = new JRadioButtonMenuItem("Shade by Study Area", false);
                shadeByStudyArea.setMnemonic('Y');
                shadingMenu.add(shadeByStudyArea);
                shadingGroup.add(shadeByStudyArea);
            shadeByNomVoltage = new JRadioButtonMenuItem("Shade by Nominal Voltage", false);
                shadeByNomVoltage.setMnemonic('V');
                shadingMenu.add(shadeByNomVoltage);
                shadingGroup.add(shadeByNomVoltage);
            shadingMenu.addSeparator();
            editLegend = new JMenuItem("Edit Shading Options...");
                editLegend.setMnemonic('E');
                shadingMenu.add(editLegend);
            shadingMenu.addSeparator();
            // shading options will be add later

        zoomMenu = new JMenu("Zoom");
            zoomMenu.setMnemonic('Z');
            this.add(zoomMenu);
            zoomOut = new JMenuItem("Zoom Out");
                zoomOut.setMnemonic('O');
                zoomOut.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0));
                zoomMenu.add(zoomOut);
            zoomIn = new JMenuItem("Zoom In");
                zoomIn.setMnemonic('I');
                zoomIn.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0));
                zoomMenu.add(zoomIn);
            zoomAll = new JMenuItem("Zoom All");
                zoomAll.setMnemonic('A');
                zoomAll.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0));
                zoomMenu.add(zoomAll);
            zoomPrev = new JMenuItem("Zoom Previous");
                zoomPrev.setMnemonic('P');
                zoomPrev.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, 0));
                zoomMenu.add(zoomPrev);
            zoomWindow = new JMenuItem("Zoom Window");
                zoomWindow.setMnemonic('W');
                zoomMenu.add(zoomWindow);
            zoomToScale = new JMenuItem("Zoom to a Specific Scale...");
                zoomToScale.setMnemonic('S');
                zoomMenu.add(zoomToScale);

        toolsMenu = new JMenu ("Tools");
            toolsMenu.setMnemonic('T');
            this.add(toolsMenu);
            txPara = new JMenuItem("Transformer Parameters...");
                txPara.setMnemonic('F');
                toolsMenu.add(txPara);
            dataMultiplier = new JMenuItem("Data Multiplier...");
                dataMultiplier.setMnemonic('U');
                dataMultiplier.setEnabled(false);
                //toolsMenu.add(dataMultiplier);
            dataModifier = new JMenuItem("Data Modification Tools...");
                dataModifier.setMnemonic('M');
                toolsMenu.add(dataModifier);
            relDataLib = new JMenuItem("Reliability Data Library...");
                relDataLib.setMnemonic('R');
                relDataLib.setEnabled(false);
                //toolsMenu.add(relDataLib);
            troubleShooting = new JMenuItem("Trouble Shooting...");
                troubleShooting.setMnemonic('T');
                toolsMenu.add(troubleShooting);
            scaleAndNorthArrow = new JMenuItem("Scale/North Arrow...");
                scaleAndNorthArrow.setMnemonic('S');
                scaleAndNorthArrow.setEnabled(false);
                //toolsMenu.add(scaleAndNorthArrow);
            options = new JMenuItem("Options...");
                options.setMnemonic('O');
                toolsMenu.add(options);
            toolsMenu.addSeparator();
            advancedTools = new JMenu("Advanced Tools");
                advancedTools.setMnemonic('A');
                advancedTools.setEnabled(true);
                toolsMenu.add(advancedTools);
                    exportToExcel = new JMenuItem("Export All Data...");
                    exportToExcel.setMnemonic('E');
                    exportToExcel.setEnabled(true);
                    advancedTools.add(exportToExcel);
                importFromExcel = new JMenuItem("Import All Data...");
                    importFromExcel.setMnemonic('I');
                    importFromExcel.setEnabled(true);
                    advancedTools.add(importFromExcel);

        analysisMenu = new JMenu("Analysis");
            analysisMenu.setMnemonic('A');
            this.add(analysisMenu);
            powerFlow = new JMenu("Power Flow");
                powerFlow.setMnemonic('P');
                analysisMenu.add(powerFlow);
                quickFlow = new JMenuItem("Radial Power Flow");
                    quickFlow.setMnemonic('R');
                    quickFlow.setAccelerator(
                        KeyStroke.getKeyStroke(KeyEvent.VK_F1, Event.CTRL_MASK));
                    powerFlow.add(quickFlow);
                netFlow = new JMenuItem("Network Power Flow");
                    netFlow.setMnemonic('N');
                    netFlow.setAccelerator(
                        KeyStroke.getKeyStroke(KeyEvent.VK_F2, Event.CTRL_MASK));
                    powerFlow.add(netFlow);
                security = new JMenuItem("Security Assessment");
                    security.setMnemonic('S');
                    security.setAccelerator(
                        KeyStroke.getKeyStroke(KeyEvent.VK_F3, Event.CTRL_MASK));
                    powerFlow.add( security );
                powerFlow.addSeparator();
                lossSum = new JMenuItem("Loss Summary...");
                    lossSum.setMnemonic('L');
                    powerFlow.add(lossSum);
            shtCkt = new JMenuItem("Short Circuit");
                shtCkt.setMnemonic('C');
                shtCkt.setAccelerator(
                    KeyStroke.getKeyStroke(KeyEvent.VK_F4, Event.CTRL_MASK));
                analysisMenu.add(shtCkt);
            reliability = new JMenu("Reliability");
                reliability.setMnemonic('R');
                analysisMenu.add(reliability);
                distRel = new JMenuItem("Radial Assessment");
                    distRel.setMnemonic('R');
                    distRel.setAccelerator(
                        KeyStroke.getKeyStroke(KeyEvent.VK_F5, Event.CTRL_MASK));
                    reliability.add(distRel);
                netRel = new JMenuItem("Network Assessment");
                    netRel.setMnemonic('N');
                    netRel.setAccelerator(
                        KeyStroke.getKeyStroke(KeyEvent.VK_F6, Event.CTRL_MASK));
                    reliability.add(netRel);
                reliability.addSeparator();
                relInd = new JMenuItem("Reliability Indices...");
                    relInd.setMnemonic('I');
                    relInd.setAccelerator(
                        KeyStroke.getKeyStroke(KeyEvent.VK_F7, Event.CTRL_MASK));
                    reliability.add(relInd);
                sensitivity = new JMenuItem("Sensitivity Analysis...");
                    sensitivity.setMnemonic('S');
                    reliability.add(sensitivity);
                risk = new JMenuItem("Risk Analysis...");
                    risk.setMnemonic('K');
                    reliability.add(risk);
                reliability.addSeparator();
                reliaOptions = new JMenuItem("Reliability Options...");
                    reliaOptions.setMnemonic('O');
                    reliability.add(reliaOptions);
            optimization = new JMenu("Optimization");
                optimization.setEnabled( false );
                optimization.setMnemonic('O');
                analysisMenu.add(optimization);
                optSwt = new JMenuItem("Switching Devices...");
                    optSwt.setMnemonic('S');
                    optimization.add( optSwt);
                optNormOpen = new JMenuItem("Normally Open Points...");
                    optNormOpen.setMnemonic('N');
                    optimization.add( optNormOpen);
            topology = new JMenu("Topology");
                topology.setMnemonic('T');
                analysisMenu.add(topology);
                buildConn = new JMenuItem("Build Connectivity");
                    buildConn.setMnemonic('C');
                    topology.add( buildConn);
                buildTree = new JMenuItem("Build Radial Tree");
                    buildTree.setMnemonic('R');
                    topology.add( buildTree);
            analysisMenu.addSeparator();
            terminate = new JMenuItem("Terminate Engines");
                terminate.setMnemonic('E');
                analysisMenu.add(terminate);

        resultsMenu = new JMenu("Results");
            resultsMenu.setMnemonic('R');
            this.add(resultsMenu);
            dataSummary = new JMenuItem("Data Summary...");
                dataSummary.setMnemonic('D');
                resultsMenu.add(dataSummary);
            costSummary = new JMenuItem("Cost Summary...");
                costSummary.setMnemonic('C');
                resultsMenu.add(costSummary);
            querySearch = new JMenuItem("Query Search...");
                querySearch.setMnemonic('Q');
                resultsMenu.add(querySearch);
            histogram = new JMenuItem("Histogram...");
                histogram.setMnemonic('H');
                histogram.setEnabled(false);
                //resultsMenu.add(histogram);
            traceToSrc = new JMenuItem("Trace to Source...");
                traceToSrc.setMnemonic('T');
                traceToSrc.setEnabled(false);
                //resultsMenu.add(traceToSrc);

        helpMenu = new JMenu("Help");
            helpMenu.setMnemonic('H');
            this.add(helpMenu);
            onlineManual = new JMenuItem("Online User Manual");
                onlineManual.setMnemonic('M');
                helpMenu.add(onlineManual);
            submitFeedback = new JMenuItem("Submit Feedback");
                submitFeedback.setMnemonic('F');
                helpMenu.add(submitFeedback);
            about = new JMenuItem("About...");
                about.setMnemonic('A');
                helpMenu.add(about);

        //set the Checkbox menus
        //setViewSelection();
    }

    private void setActionListeners(){
        newPrj.addActionListener(alNewPrj);
        openPrj.addActionListener(alOpenPrj);
        importZones.addActionListener(alImportZones);
        savePrj.addActionListener(alSavePrj);
        savePrjAs.addActionListener(alSavePrjAs);
        exportData.addActionListener(alExportData);
        loadDftLib.addActionListener(alLoadDftLib);
        loadBgImg.addActionListener( alLoadBgImg);
        for (int i = 0; i < PersonalInfo.MAX_RECENT_PRJ; i++) {
            recentPrjs[i].addActionListener(alOpenRecentPrj);
        }
        exit.addActionListener(alExit);

        undo.addActionListener( alUndo);
        redo.addActionListener( alRedo);
        rotate.addActionListener(alRotate);
        toggle.addActionListener(alToggle);
        delete.addActionListener(alDelete);
        copy.addActionListener(alCopy);
        cmpInfo.addActionListener(alCmpInfo);
        if (SysConst.DEBUG_MODE > 0)
            cmpInfoDebug.addActionListener(alCmpInfoDebug);
        findCmp.addActionListener(alFindCmp);

        selectToSource.addActionListener(alSelectTraceSource);
        selectAwayFromSource.addActionListener(alSelectTraceSource);
        selectDeenergized.addActionListener(alSelectDeenergized);
        selectStudyArea.addActionListener(alSelectStudyArea);
        selectZone.addActionListener(alSelectZone);
        selectVoltageLevel.addActionListener(alSelectVoltageLevel);
        selectOpenSwt.addActionListener(alSelectOpenSwt);
        invertSelection.addActionListener(alInvertSelection);
        selectAll.addActionListener(alSelectAll);
        activeTemp.addActionListener(alActiveTemp);
        dftTemp.addActionListener(alDftTemp);
        commonZone.addActionListener(alCommon);
        commonDefaultTemplate.addActionListener(alCommon);
        commonName.addActionListener(alCommon);
        commonPhase.addActionListener(alCommon);
        commonVoltageLevel.addActionListener(alCommon);
        setSelectionToStudyArea.addActionListener(alStudyArea);
        addSelectionToStudyArea.addActionListener(alStudyArea);
        removeSelectionFromStudyArea.addActionListener(alStudyArea);
        clearStudyArea.addActionListener(alStudyArea);
        ungroup.addActionListener(alUngroup);
        combineSelectedSections.addActionListener(alCombineSelectedSections);
        insertNode.addActionListener(alInsertNode);

        text.addActionListener(alText);
        showNodes.addActionListener(alShowNodes);
        legend.addActionListener(alLegend);
        scale.addActionListener(alScale);
        gridLine.addActionListener(alGridLine);
        highLightAll.addActionListener(alHighLight);
        highLightNone.addActionListener(alHighLight);
        highLightOpenPoints.addActionListener(alHighLight);
        highLightProtection.addActionListener(alHighLight);
        highLightSect.addActionListener(alHighLight);
        highLightSelected.addActionListener(alHighLight);
        layerMngr.addActionListener(alLayerMngr);
        freeze.addActionListener( alFreeze);
        refresh.addActionListener(alRefresh);

        editLegend.addActionListener(alEditLegend);
        noShading.addActionListener(alShadeOpt);
        shadeByZone.addActionListener(alShadeOpt);
        shadeByStudyArea.addActionListener(alShadeOpt);
        shadeByNomVoltage.addActionListener(alShadeOpt);

        zoomOut.addActionListener(alZoomOut);
        zoomIn.addActionListener(alZoomIn);
        zoomAll.addActionListener(alZoomAll);
        zoomPrev.addActionListener(alZoomPrev);
        zoomWindow.addActionListener(alZoomWindow);
        zoomToScale.addActionListener(alZoomToScale);

        txPara.addActionListener(alTxPara);
        troubleShooting.addActionListener(alTroubleShooting);
        dataModifier.addActionListener(alDataModifier);
        exportToExcel.addActionListener( alExportToExcel);
        importFromExcel.addActionListener( alImportFromExcel);
        options.addActionListener(alOptions);

        buildConn.addActionListener(alBuildConn);
        buildTree.addActionListener(alBuildTree);
        quickFlow.addActionListener(alQuickFlow);
        netFlow.addActionListener(alNetFlow);
        security.addActionListener( alSecurity);
        lossSum.addActionListener(alLossSum);
        distRel.addActionListener(alDistRel);
        netRel.addActionListener(alNetRel);
        relInd.addActionListener(alRelInd);
        reliaOptions.addActionListener(alReliaOptions);
        sensitivity.addActionListener(alSensitivity);
        risk.addActionListener(alRisk);
        shtCkt.addActionListener(alShtCkt);
        optSwt.addActionListener( alOptSwt);
        terminate.addActionListener(alTerminate);

        dataSummary.addActionListener(alDataSummary);
        costSummary.addActionListener(alCostSummary);
        querySearch.addActionListener(alQuerySearch);

        onlineManual.addActionListener(alOnlineManual);
        submitFeedback.addActionListener(alSubmitFeedback);
        about.addActionListener(alAbout);
    }
}

class UpdateProgressThread extends Thread{
    ButtonPanel btnPanel;
    int mode;
    public UpdateProgressThread(ButtonPanel p, int m) {
        btnPanel = p;
        mode = m;
    }
    public void run() {
        try {
            int prev = 0;
            btnPanel.lblLoading.setVisible(true);
            btnPanel.progressBar.setVisible(true);
            switch(mode) {
                case ButtonPanel.OPEN_MODE:
                    SysConst.progressMsg = "Loading..."; break;
                case ButtonPanel.SAVE_MODE:
                    SysConst.progressMsg = "Saving...";  break;
                case ButtonPanel.CONN_MODE:
                    SysConst.progressMsg = "Finding Connectivity..."; break;
                case ButtonPanel.COPY_MODE:
                    SysConst.progressMsg = "Copy file..."; break;
                case ButtonPanel.ENGN_MODE:
                    SysConst.progressMsg = "Running Analysis Engine..."; break;
                default:
                    SysConst.progressMsg = "Processing...";  break;
            }
            btnPanel.setLoadingText(SysConst.progressMsg);
            btnPanel.setProgress(SysConst.progress);

            while(true) {
                if (SysConst.progress>prev) {
                    btnPanel.setLoadingText(SysConst.progressMsg);
                    btnPanel.setProgress(SysConst.progress);
                    prev = SysConst.progress;
                    if (SysConst.progress >= btnPanel.progressBar.getMaximum())
                        break;
                } else{
                    sleep(500); //sleep for 0.5 sec
                }
            }
        } catch(InterruptedException e) {
        } finally {
            btnPanel.lblLoading.setVisible(false);
            btnPanel.progressBar.setVisible(false);
            SysConst.progress=btnPanel.progressBar.getMinimum();
            SysConst.progressMsg = null;
        }
    }
}//end of class UpdateProgressThread
